💥打包的 `.exe` 闪退了?别慌!教你逐步排查 PyInstaller 打包的所有错误!
- 🛠 运行 `.exe` 查看报错信息
- ✅ 正确姿势:
- ⚠ importlib 动态导入导致打包失败
- ❓什么是动态导入?
- ✅ 解决方式:
- 📦 包元数据丢失问题:`importlib.metadata.PackageNotFoundError`
- 🎯 根本原因:
- ✅ 解决方法一:打包命令添加参数
- ✅ 解决方法二:使用 `.spec` 文件方式
- ❌ DLL 加载失败:WinError 127
- ✅ 修复步骤:
- ✅ 第一步:找到 torch 的 lib 路径
- ✅ 第二步:修改 `.spec` 文件
- 🔧 终极解决方案:用 `PyInstaller.__main__` 写一个自定义 `package.py`
- ✅ 优点:
- 🔚 总结
- 🧠 附:打包常见库建议参数
前面的只是学习,虽然问题解决了,但是一个个问题又冒出来了,可以直接看最后一部分,我换了一个方法。
🛠 运行 .exe
查看报错信息
很多人在直接双击 .exe
文件时,会发现它“一闪而过”就没了。这是因为程序崩溃了,报错信息来不及显示。
✅ 正确姿势:
- 打开终端(CMD 或 PowerShell)
- 切换到
.exe
文件所在目录 - 运行:
cd dist\your_program
.\your_program.exe
如图所示:
⚠ importlib 动态导入导致打包失败
❓什么是动态导入?
很多库使用 importlib.import_module("模块名")
来动态加载模块,而不是传统的 import 模块名
。
PyInstaller 只能分析静态导入,遇到动态导入时,它就不知该打包啥了,运行就会提示模块缺失或功能失效。
✅ 解决方式:
在 spec
文件的 datas
中手动添加:
datas = [
(r"G:\anaconda\envs\pcb\Lib\site-packages\ultralytics", "ultralytics"),
]
重新打包即可。
📦 包元数据丢失问题:importlib.metadata.PackageNotFoundError
报错信息:
importlib.metadata.PackageNotFoundError: No package metadata was found for torchvision
🎯 根本原因:
PyInstaller 默认不会打包 metadata,而有些库(如 ultralytics
)使用:
importlib.metadata.version("torchvision")
来获取依赖库的版本,因此需要明确告诉它:把 metadata 一起带上!
✅ 解决方法一:打包命令添加参数
pyinstaller --onefile ^
--collect-all ultralytics ^
--copy-metadata=torch ^
--copy-metadata=torchvision ^
--copy-metadata=ultralytics ^
main_window.py
✅ 解决方法二:使用 .spec
文件方式
在 .spec
中添加:
from PyInstaller.utils.hooks import copy_metadata
datas += copy_metadata('torch')
datas += copy_metadata('torchvision')
datas += copy_metadata('ultralytics')
❌ DLL 加载失败:WinError 127
错误提示:
OSError: [WinError 127] 找不到指定模块
Error loading "torch\lib\caffe2_detectron_ops.dll"
说明 PyInstaller 没把某些 .dll
一起打包!
✅ 修复步骤:
✅ 第一步:找到 torch 的 lib 路径
运行:
python -c "import torch; print(torch.__path__)"
假设路径为:
G:\anaconda\envs\pcb\Lib\site-packages\torch
✅ 第二步:修改 .spec
文件
import glob
import os
torch_dlls = [
(f, os.path.join('torch', 'lib')) for f in glob.glob(
r'G:\anaconda\envs\pcb\Lib\site-packages\torch\lib\*.dll'
)
]
a = Analysis(
['main_window.py'],
...
binaries=torch_dlls,
datas=[
(r"G:\anaconda\envs\pcb\Lib\site-packages\ultralytics", "ultralytics"),
(r"G:\anaconda\envs\pcb\Lib\site-packages\torch", "torch"),
(r"G:\anaconda\envs\pcb\Lib\site-packages\torchvision", "torchvision"),
],
...
)
🔧 终极解决方案:用 PyInstaller.__main__
写一个自定义 package.py
上面的方法,始终有问题。耽误了我一天的时间,最终终于找到了解决的方案。换了一种方法。
import PyInstaller.main
你可以自己写一个 package.py
脚本统一管理打包逻辑:
import PyInstaller.__main__
PyInstaller.__main__.run([
'--onefile',
'--nowindowed',
'-n', 'defect_detect',
'-i', 'ui/ui_imgs/icons/目标检测.ico',
'--add-data=ui/ui_imgs/icons;ui/ui_imgs/icons',
'--add-data=view/style.css;view',
'--copy-metadata=torch',
'--copy-metadata=torchvision',
'--copy-metadata=ultralytics',
'--collect-all', 'ultralytics',
'main_window.py',
])
✅ 优点:
- 不再需要手动修改
.spec
- 自动包含 metadata
- 可重复运行,一键打包!
🔚 总结
错误类型 | 解决方案 |
---|---|
exe 闪退 | 命令行运行查看报错 |
动态导入库找不到 | datas手动添加路径 |
metadata 丢失 | 添加 --copy-metadata 参数 |
DLL 加载失败 | torch/lib/*.dll 添加进 binaries |
打包太麻烦 | 用 PyInstaller API 脚本自动化 |
🧠 附:打包常见库建议参数
库名称 | 打包建议 |
---|---|
ultralytics | --collect-all ultralytics |
torch | --copy-metadata=torch + 添加 dll |
torchvision | --copy-metadata=torchvision |
numpy | 一般自动打包 |
matplotlib | 建议 --collect-submodules |
如果你觉得本篇文章对你有帮助,欢迎点赞、收藏、转发!🚀
更多 PyInstaller 技术细节、实战案例持续更新中~
有任何问题也欢迎评论区留言交流!