From 9dbaabd4a921a0926c8cf9ca5d9a5bae84d79649 Mon Sep 17 00:00:00 2001 From: RoyirinRosmontis Date: Wed, 16 Sep 2026 23:45:40 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9ANuitka=20onefile=20?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lite/main.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lite/main.py b/lite/main.py index c82ebb9..c96163f 100644 --- a/lite/main.py +++ b/lite/main.py @@ -61,10 +61,21 @@ _BASE_WINDOW_HEIGHT = 470 # 内容区 + 加大日志区 + 底部两行提示小 # 已被打包为 EXE(PyInstaller 的 sys.frozen / Nuitka 的 __compiled__): # BASE_DIR -> 内置数据目录:PyInstaller 用 _MEIPASS,Nuitka onefile 用 # __file__ 所在解压临时目录(无 _MEIPASS 时回退) -# PERSIST_DIR -> EXE 所在目录,服务安装等需要持久化的操作都放这里 +# PERSIST_DIR -> EXE 所在目录,服务安装等需要持久化的操作都放这里。 +# Nuitka onefile 的 sys.executable 指向 TEMP\onefile_* 解包子进程,不能用它 +# 定位用户启动的原始 EXE;优先使用 __compiled__.containing_dir,旧版 Nuitka +# 再回退到 sys.argv[0](官方保证它指向原始 onefile 路径)。 +def _frozen_executable_dir(): + if "__compiled__" in globals(): + compiled_dir = getattr(globals()["__compiled__"], "containing_dir", None) + if compiled_dir: + return Path(compiled_dir).resolve() + return Path(sys.argv[0]).resolve().parent + return Path(sys.executable).resolve().parent + if getattr(sys, 'frozen', False) or "__compiled__" in globals(): BASE_DIR = Path(getattr(sys, "_MEIPASS", None) or Path(__file__).resolve().parent) - PERSIST_DIR = Path(sys.executable).resolve().parent + PERSIST_DIR = _frozen_executable_dir() else: BASE_DIR = Path(__file__).resolve().parent PERSIST_DIR = BASE_DIR @@ -2390,7 +2401,7 @@ class MainWindow(QWidget): # 冻结程序必须放到当前 EXE 的目录,便于用户关闭旧版后就地替换; # 源码调试则仍写入源码目录,避免误把测试文件写到 Python 安装目录。 if getattr(sys, 'frozen', False) or "__compiled__" in globals(): - download_dir = Path(sys.executable).resolve().parent + download_dir = _frozen_executable_dir() else: download_dir = PERSIST_DIR save_path = download_dir / f"Royirin Rosmontis Private Proxy {self._latest_version}.exe"