2.1.5:修「Windows 7 装完报 dll 缺失」 用户报:学校的电脑是 Windows 7,装完提示缺 DLL。 == 根因不是漏打包,是 Python 版本越界 == Python 3.8 -> 最后一个支持 Windows 7 的版本 Python 3.9+ -> 只支持 Windows 8 及以上 Python 3.9 起用到了 api-ms-win-core-path-l1-1-0.dll 里的 PathCchCanonicalizeEx,而这个 DLL **Windows 7 上根本不存在**, 也没法用 api-set 转发(那套机制只在 Win8+ 生效)。 所以之前用 3.11 打出来的包,在 Win7 上必然报缺 DLL —— **那个 DLL 不是"忘了放进包",是"放进去也没用"。** 顺带说明:包里那 47 个 api-ms-win-core-*.dll 转发库正是 Python 为兼容 Win7 才带上的 —— 上游本来就考虑过 Win7, 只是 3.11 这个版本号越界了。 == 改法 == 1. **改用 Python 3.8 打包,而且选 32 位** 32 位在 Win7 的 32 位和 64 位系统上都能跑,学校不用分两种发。 (64 位的包在 32 位 Windows 上直接起不来。) 依赖固定到 3.8 能用的版本: Pillow==9.5.0(最后一个支持 3.8 的) pyinstaller 6.x(保持 _internal 布局,和安装包/测试/卸载逻辑一致; 5.x 会把依赖摊在根目录,导致"_internal 在"那一项失败) 2. **打包脚本主动拦** windows\build_exe.ps1 打包前先校验 Python: * 找不到 3.8 -> 报错并给出安装命令 * 版本不是 3.8 -> 直接 throw,而不是默默打一个别人装不上的包 * 不是 32 位 -> 警告 Python 从 YKXMZ_PY 环境变量或常见路径里找,不写死。 3. **新增 Win7 兼容校验** _build\check_win7_compat.py 盯三件事:内嵌是不是 3.8 的运行库、**有没有**那个要命的 DLL、 exe 是不是 32 位。打包时和回归套件(3a9 关)里都会跑, 不过就拒绝出包。 == 顺手修的 == _build/test_installer_cycle.py 里写死了 ykxmz-setup-1.8.2.exe, 于是一直在**装一个不存在的旧包** -> 静默失败 -> 报出一堆 莫名其妙的失败("配对码实际是 xxx"、"版本显示 v1.8.2")。 改成自动找 dist 下版本号最新的包(按数字段排序,不能按字符串, 否则 1.9.0 会排到 2.1.4 前面)。 == 验证(用户要求:自己测一遍,没问题再上传)== 全量回归 42 个阶段全 PASS(含新的 "Windows 7 兼容" 关) 安装包完整周期 20/20 Win7 校验:python38.dll / 无 api-ms-win-core-path / 32 位 实际启动打包的 EXE:进程活着、TCP 监听、UDP 自动发现在听、 连接能建立(日志里有"设备接入") 产物扫描:三件全部干净(无旧密码、无服务器 IP) 提交前泄漏闸门通过 安装包体积 14.4 MB -> 9.0 MB。