# -*- mode: python ; coding: utf-8 -*- from pathlib import Path from PyInstaller.utils.hooks import collect_all # 强制收集 PyQt5 全部模块及二进制文件 qt_datas, qt_binaries, qt_hiddenimports = collect_all('PyQt5') # 只内置 config.json(普通设置)。nodes.json / pac_*.json 属用户数据: # 运行时读 %LOCALAPPDATA%\RRPP(首启自动创建模板 / 从 CDN 拉取),不进 EXE。 _JSON_DATAS = [(str(Path(SPECPATH) / 'config.json'), '.')] _TUN_RUNTIME = [ (str(Path(SPECPATH) / 'runtime' / name), '.') for name in ('tun2socks.exe', 'wintun.dll', 'LICENSE.tun2socks.txt', 'LICENSE.wintun.txt', 'README.txt') ] print(f"[spec] 打包 json 数据文件: {[Path(src).name for src, _ in _JSON_DATAS]}") # 自定义 manifest:普通权限运行 + 声明 PerMonitorV2 DPI 感知, # 避免程序在不同缩放比例的显示器之间移动时被 Windows 位图拉伸。 _MANIFEST = r''' Royirin Rosmontis Private Proxy Lite PerMonitorV2, PerMonitor, system true/pm ''' a = Analysis( ['main.py'], pathex=[], binaries=qt_binaries, datas=[('ico.ico', '.')] + _JSON_DATAS + _TUN_RUNTIME + qt_datas, hiddenimports=qt_hiddenimports, hookspath=[], hooksconfig={}, runtime_hooks=[], # 排除 Nuitka 构建链相关模块(venv 里装了 Nuitka,但 PyInstaller 产物不需要) excludes=['nuitka', 'zstandard', 'ordered_set'], noarchive=False, optimize=0, ) pyz = PYZ(a.pure) exe = EXE( pyz, a.scripts, a.binaries, a.datas, [], name='Royirin Rosmontis Private Proxy Lite Python', debug=False, bootloader_ignore_signals=False, strip=False, # UPX 会压缩资源段(含图标),冷缓存下 Explorer 可能提取不到图标导致任务栏空白 upx=False, upx_exclude=[], runtime_tmpdir=None, console=False, disable_windowed_traceback=False, argv_emulation=False, target_arch=None, codesign_identity=None, entitlements_file=None, icon=['ico.ico'], manifest=_MANIFEST, )