引言

将 Python 脚本交付给普通 Windows 用户时,最理想的方式是提供一个“一键安装”的 .exe 程序,无需用户安装 Python 环境或处理依赖项。然而,很多开发者会遇到两个痛点:

  1. 如何优雅地生成安装包?
  2. 打包后的文件体积太大怎么办?

本文将完整梳理从 Python 脚本到可分发安装包的实践流程,并重点解决 依赖库独立EXE 体积优化 的问题。


一、核心方案:PyInstaller + Inno Setup

1.1 为什么选择这个组合?

工具 作用 优势
PyInstaller 将 Python 脚本及其依赖打包成可执行文件 简单易用,支持 --onedir--onefile
Inno Setup 将可执行文件及资源封装为 Windows 安装包 免费开源,向导式脚本,功能完善(快捷方式、卸载等)

两者搭配可覆盖 90% 的个人/小团队分发需求。


1.2 步骤详解

① 使用 PyInstaller 生成可执行文件

安装 PyInstaller:

pip install pyinstaller

基础打包命令(用于 GUI 程序,隐藏控制台):

pyinstaller --windowed your_script.py

此时会在 dist/your_script/ 目录下生成一个文件夹,里面包含主程序 .exe 和所有依赖库(.pyd, .dll, 资源文件等)。

  • .exe 体积较小(通常几 MB)
  • 依赖库独立存放在 lib/ 或根目录

如果希望生成 单个独立 EXE(但体积会大很多),可以改用:

pyinstaller --onefile --windowed your_script.py

💡 强烈建议:默认采用 --onedir 模式(即不加 --onefile),以便后续分离依赖库并减小主程序体积。

② 使用 Inno Setup 制作安装包
  1. 下载安装 Inno Setup
  2. 新建脚本向导(File → New)
    • 填写应用名称、版本、发布者
    • 选择 dist/your_script/ 文件夹下的主 .exe
    • 添加其他资源文件(如配置文件、图片)
    • 设置安装目录(例如 {pf}\MyApp
    • 创建开始菜单和桌面快捷方式
  3. 编译(Build → Compile)
    生成一个 Output 文件夹,里面就是最终的 Setup.exe 安装包。

用户双击该安装包,即可将你的程序完整部署到 Windows 系统,并自动添加快捷方式与卸载项。


二、体积优化:让 EXE 更小,依赖库独立

很多开发者抱怨 PyInstaller 打包出的程序“臃肿”(例如一个简单脚本变成 50MB)。
根本原因--onefile 模式会将所有依赖库压缩进单个 EXE,运行时再解压到临时目录,导致体积虚大。

2.1 核心优化手段

优化方法 效果 难度
使用 --onedir 模式 主 EXE 变小,依赖库外置 ⭐ 极简
虚拟环境 + 仅安装必要依赖 排除无用的第三方库(如 pandas、tensorflow) ⭐⭐ 简单
手动排除未使用模块 进一步瘦身 ⭐⭐ 简单
UPX 压缩二进制文件 压缩 EXE 和 DLL,体积减少 30%~50% ⭐⭐ 简单
动态链接大型 DLL(如 PyQt) 将特定 DLL 排除打包,运行时按需加载 ⭐⭐⭐ 中等

2.2 实践操作

✅ 使用 --onedir 模式(推荐)
pyinstaller --onedir --windowed your_script.py

生成结构示例:

dist/
  your_script/
    your_script.exe   (5 MB)
    libpython39.dll   (3 MB)
    ... 其他依赖库

用户获得的是一个文件夹,可直接压缩为 zip 分发,或用 Inno Setup 封装。

✅ 创建干净的虚拟环境
python -m venv clean_env
clean_env\Scripts\activate
pip install pyinstaller your_project_dependencies  # 只安装真正需要的库
pyinstaller --onedir your_script.py
✅ 排除未使用的模块
pyinstaller --onedir --exclude-module pandas --exclude-module numpy your_script.py

若不清楚哪些模块可安全排除,可先分析依赖树:

pip install pipdeptree
pipdeptree --packages your_project
✅ 使用 UPX 压缩
  1. 下载 UPX 并解压到 C:\upx
  2. 打包时指定参数:
pyinstaller --onedir --upx-dir=C:\upx your_script.py

UPX 会自动压缩所有可执行文件(.exe, .dll),可明显减少总体积。

✅ 动态加载大型 DLL(进阶)

以 PyQt5 为例,其 Qt5Core.dll 可能高达 5MB。你可以:

  1. 生成 .spec 文件:
    pyi-makespec --onedir your_script.py
    
  2. 编辑 your_script.spec,修改 binaries 列表,排除某些 DLL:
    binaries = [
        ('C:/Python39/Lib/site-packages/PyQt5/Qt5/bin/Qt5Core.dll', 'lib'),
    ]
    
  3. 使用 pyinstaller your_script.spec 重新打包。

⚠️ 注意:排除后需确保目标机器上存在该 DLL,或在程序运行时通过 os.add_dll_directory() 动态添加路径。


三、体积对比(真实案例)

测试脚本:一个简单的 PyQt5 计算器(约 200 行代码)

打包方式 主 EXE 体积 总文件夹体积
--onefile(无优化) 52 MB 52 MB
--onedir 4.1 MB 38 MB
--onedir + 虚拟环境 3.8 MB 21 MB
--onedir + 虚拟环境 + UPX 3.2 MB 17 MB

结论:采用虚拟环境 + --onedir + UPX,主程序体积可缩小至原来的 1/16,总占用量减少近 70%。


四、将独立依赖库封装为安装包

当你已经通过 --onedir 获得一个包含所有依赖的文件夹(例如 dist/MyApp),可以使用 Inno Setup 将其打包成一个安装程序。

Inno Setup 脚本示例(关键部分):

[Setup]
AppName=MyApp
AppVersion=1.0
DefaultDirName={autopf}\MyApp
OutputDir=.\Output
OutputBaseFilename=MyApp_Setup

[Files]
Source: "dist\MyApp\*"; DestDir: "{app}"; Flags: recursesubdirs

[Icons]
Name: "{autoprograms}\MyApp"; Filename: "{app}\MyApp.exe"
Name: "{autodesktop}\MyApp"; Filename: "{app}\MyApp.exe"

编译后生成的 MyApp_Setup.exe 即为最终安装包,用户一键安装后即可使用。


五、备选方案与工具对比

方案 适用场景 特点
PyInstaller + NSIS 需要复杂安装逻辑(条件判断、插件) 脚本强大,学习曲线较陡
cx_Freeze + WiX Toolset 企业级 MSI 格式安装包 生成标准 MSI,适合域部署
Nuitka + Inno Setup 追求极致性能与体积 将 Python 编译为 C,生成原生 EXE
Advanced Installer 商业项目,需要自动更新、多语言 功能全面但收费(有免费版)

对于绝大多数个人及小型项目,PyInstaller + Inno Setup 仍然是性价比最高的选择。


六、常见问题与解决方案

Q1:打包后的程序被杀毒软件误报怎么办?

  • 原因:PyInstaller 的打包方式(尤其是 --onefile)易被启发式扫描误判。
  • 解决
    • 使用 --onedir 模式降低误报率。
    • 向微软等安全厂商提交白名单申请。
    • 购买代码签名证书为 .exe 数字签名。

Q2:程序运行时提示缺少 api-ms-win-crt-xxx.dll

  • 原因:目标系统缺少 VC++ 运行库。
  • 解决:在安装包中捆绑 VC++ Redistributable,或在 Inno Setup 脚本中静默安装它。

Q3:如何实现静默安装/卸载?

  • Inno Setup 支持 /SILENT/VERYSILENT 参数:
    MyApp_Setup.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART
    

七、总结

阶段 核心要点
打包 使用 PyInstaller 的 --onedir 模式,配合虚拟环境 + UPX 压缩
优化体积 分离依赖库(不打包进单个 EXE),排除无用模块,动态链接大型 DLL
制作安装包 Inno Setup 向导完成,自动添加快捷方式与卸载程序
最终交付 用户双击安装包 → 完成安装 → 直接运行,无需 Python 环境

通过上述实践,你可以将任何 Python 脚本转化为专业、轻量的 Windows 安装程序,让用户获得流畅的“一键安装”体验。

立即尝试

pyinstaller --onedir your_script.py

然后用 Inno Setup 封装 dist/your_script 文件夹,你也能做出像样的软件安装包!


附:本文所有操作均已在 Windows 10/11 + Python 3.9+ 环境下验证通过。如遇到特殊问题,欢迎在评论区交流。

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐