833 字
4 分钟
把 Electron 和 Python 塞进一个 zip

这个应用的形态是:Electron 34 套一个 Vue 3 界面,真正的抓取逻辑全是 Python。

开发的时候很舒服:改 Vue 热更新,改 Python 下次点按钮就生效。打包发给别人是另一回事——对方电脑上没有 Python。

两层打包#

第一层,Python 冻成 exe。

PyInstaller onedir 模式,输出到 build-backend/backend/,里面是一个 backend.exe 加一个 _internal/ 目录。

用 onedir 不用 onefile:onefile 每次启动都要把整个运行时解压到临时目录,启动慢,而且杀毒软件对”自解压的程序”格外敏感,误报率高得多。

第二层,electron-builder 把这个目录拷进 resources/backend/。

最终产物:

dist-electron/
SocialArchiver-1.2.5-win.zip # 解压即用
SocialArchiver-1.2.5-win.exe # NSIS 安装包
win-unpacked/ # 同内容,本机直接跑

坑一:只拷 exe 一定坏#

这是我这项目里被问得最多的问题。

有人从 win-unpacked 里把 Social Archiver.exe 单独拷到桌面,双击,报错。

Electron 的 exe 只是入口,它要去找同目录下的 resources/app.asar、resources/backend/backend.exe、_internal/ 里几千个 DLL 和 Python 模块。少任何一个都起不来。

所以文档里反复写:必须保留整个目录,要么发 zip,要么发安装包。

坑二:gallery-dl 装了两份#

X 和 Instagram 都靠 gallery-dl。它被打进了冻结的后端里——但冻结的版本永远是打包那天的版本。

gallery-dl 更新很勤,平台一改接口它就得跟。冻结版没法 pip install -U。

所以运行时的策略是:先用 shutil.which('gallery-dl') 找系统里装的,找到就用系统的(用户可以自己升级);找不到才用冻结的兜底。

这样既能”解压即用、不用装 Python”,又能”想升级随时升”。

坑三:中文乱码#

打包版有一段时间日志全是乱码。

原因:subprocess 在 Windows 上的默认编码跟着系统区域走,中文系统是 GBK,而管道里传的是 UTF-8。

修了两处:cli.py 里 _force_utf8_stdio() 强制重设 stdin/stdout,spawn 的时候显式指定编码。

还有个连带问题:stdout 是 JSON Lines,一行一条。如果缓冲区没行缓冲,一条消息可能被切成两半发出来,前端解析失败,界面一直转圈。所以 spawn 时开了行缓冲。

坑四:SmartScreen#

安装包没有代码签名。

第一次运行,Windows 会弹「Windows 已保护你的电脑」。处理方式是「更多信息」→「仍要运行」。

这是预期行为,不是中毒。想消掉只有一条路:买 Authenticode 证书签 exe,一年几千块。个人项目不值当,所以在 README 里写清楚怎么绕过。

企业环境部署的话,可以在组策略里给这个 exe 加路径排除。

坑五:环境门卫#

PyInstaller 打包前检查 Python 版本,低于 3.9 直接报错退出。

不检查的话,低版本打出来的包能生成,但运行时一堆语法错误,排查起来很痛苦。

坑六:输出目录被占用#

win-unpacked 里的 exe 还在跑,再打包就失败——文件被锁。

解决方法是要么先关掉,要么指定临时输出目录:

Terminal window
npm run electron:build -- --config.directories.output=%TEMP%\sa-electron-out

打完再拷回来。


打包本身的代码量不大,但它决定了别人能不能用。开发环境跑得通,和发给朋友能双击打开,中间隔着的全是这类细节。

把 Electron 和 Python 塞进一个 zip
https://mssworld.me/posts/packaging-electron-python/
作者
m.s.s
发布于
2026-10-31
许可协议
CC BY-NC-SA 4.0