diff --git a/desktop_engine.py b/desktop_engine.py index 9ff3bf0..de73c91 100644 --- a/desktop_engine.py +++ b/desktop_engine.py @@ -28,6 +28,19 @@ def _pick_port(): def _parent_alive(pid): + # Windows: os.kill(pid, 0) KHONG kiem tra ton tai — no goi + # TerminateProcess (giai thich: moi sig khac CTRL_C/BREAK deu terminate). + # => watchdog se GIET LUON tien trinh cha (Tauri) sau 1s dau tien. + # Dung OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION): tra ve NULL khi + # pid khong con ton tai. + if os.name == "nt": + import ctypes + PROCESS_QUERY_LIMITED_INFORMATION = 0x1000 + h = ctypes.windll.kernel32.OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, pid) + if not h: + return False # tien trinh da chet + ctypes.windll.kernel32.CloseHandle(h) + return True try: os.kill(pid, 0) return True @@ -38,25 +51,31 @@ def _parent_alive(pid): def main(): os.environ.setdefault("SF_DESKTOP", "1") + # Log dir tao SOM de stderr co the tro vao file (xem duoi). + log_dir = os.path.join( + os.environ.get("APPDATA") or os.path.expanduser("~"), + APP_DATA_DIR_NAME, "logs", + ) + try: + os.makedirs(log_dir, exist_ok=True) + except OSError: + log_dir = os.path.expanduser("~") + # Windowed app (engine.spec console=False): Windows khong tao console -> # sys.stdout/sys.stderr = None -> uvicorn logging crash - # ('NoneType' object has no attribute 'isatty'). Thay bang file rong de - # uvicorn (StreamHandler/isatty) luon co stream hop le. + # ('NoneType' object has no attribute 'isatty'). Tro stdout/stderr vao + # FILE (KHONG phai devnull) — neu devnull thi moi exception bi nuot im + # lang (trieu chung 'stuck khong logs, khong loi'). if sys.stdout is None: - sys.stdout = open(os.devnull, "w") + sys.stdout = open(os.path.join(log_dir, "stdout.log"), "w", encoding="utf-8") if sys.stderr is None: - sys.stderr = open(os.devnull, "w") + sys.stderr = open(os.path.join(log_dir, "stderr.log"), "w", encoding="utf-8") port = _pick_port() os.environ["SF_PORT"] = str(port) # Log ra file — khi dong goi console=False, stdout khong nhin thay duoc. try: - log_dir = os.path.join( - os.environ.get("APPDATA") or os.path.expanduser("~"), - APP_DATA_DIR_NAME, "logs", - ) - os.makedirs(log_dir, exist_ok=True) logging.basicConfig( level=logging.INFO, format="%(asctime)s %(levelname)s %(name)s: %(message)s",