扩展PyInstaller 使其拥有单文件安装功能不用每次都解压执行
Project description
PyInstallerEx
增强版 PyInstaller 打包工具,可创建具有安装功能的单文件可执行程序
🎯 项目概述
PyInstallerEx 是一个基于 PyInstaller 的增强版打包工具,能够将 Python 应用程序打包成具有安装功能的单文件可执行程序。与传统的 PyInstaller 创建独立可执行文件不同,PyInstallerEx 创建的安装程序可执行文件具有以下特点:
- 首次运行时提取:应用程序被提取到临时目录
- 重复使用已安装版本:后续运行使用已经提取的版本
- 自动清理:智能管理临时文件
🌟 特色功能
- 单文件分发:单个可执行文件包含完整应用程序
- 自动安装:首次运行时自动提取到临时目录
- 智能缓存:后续运行直接使用已安装版本,自动清理旧缓存(基于
ex_{filename}_{md5}目录模式) - 灵活解压模式:支持解压到系统临时目录或 exe 所在目录(通过
--extract-mode参数控制) - 跨平台支持:Windows、Linux x86/ARM全平台覆盖
- 配置灵活:支持嵌入式配置读取,命令行参数覆盖配置文件
🔧 环境要求
Python
- Python >= 2.7(推荐 Python 3.8+)
- 确保 Python 已添加到系统 PATH
Rust(仅当需要重新构建启动器时)
- Rust >= 1.70
- 下载地址: https://rustup.rs/
注意: 项目已包含预编译的启动器文件 (
bin/launcher_windows.exe),大多数情况下不需要重新构建。
⚙️ 工作原理
- PyInstaller 打包:使用 PyInstaller 的
--onedir模式创建完整的应用程序目录 - 配置处理:应用用户配置并生成元数据
- 压缩:将应用程序目录压缩为 ZIP 文件
- 二进制合并:将平台特定的启动器二进制文件与 ZIP 文件合并
- 最终可执行文件:创建一个处理提取和执行的单个可执行文件
🚀 快速开始
Windows 用户
方式一:一键安装(推荐)
# 在项目根目录运行
script\install.bat
这将自动完成:
- 创建虚拟环境
.venv - 安装所有依赖
- 验证安装
方式二:手动安装
# 1. 创建并激活虚拟环境
python -m venv .venv
.venv\Scripts\Activate.ps1 # PowerShell
# 或
.venv\Scripts\activate.bat # CMD
# 2. 安装项目
pip install -e .
# 3. (可选)构建启动器(如果 bin/launcher_windows.exe 不存在)
script\build_launchers.bat
Linux/Mac 用户
# 1. 创建并激活虚拟环境
python -m venv .venv
source .venv/bin/activate
# 2. 安装项目
pip install -e .
# 3. (可选)构建启动器
bash build_launchers.sh
📦 安装
从 PyPI 安装最新版本:
pip install pyinstallerex
📖 使用方法
基本用法
# 使用 pyinstallerex 命令
pyinstallerex your_script.py
# 使用 PyInstallerEx 命令
PyInstallerEx your_script.py
# 使用 Python -m 方法(推荐)
python -m PyInstallerEx your_script.py
使用配置文件
python -m PyInstallerEx your_script.py --cfg config.json
查看帮助
python -m PyInstallerEx --help
示例
# 测试打包
python -m PyInstallerEx test\test_script.py --cfg test\test_config.json
# 运行生成的可执行文件
test\test_script.exe # Windows
./test/test_script # Linux/Mac
示例项目
项目 examples/ 目录下提供了多个示例,帮助快速上手各种打包模式:
| 序号 | 示例目录 | 演示功能 | 核心参数 |
|---|---|---|---|
| 01 | 01 - hello_world |
最基础打包,使用默认 PyInstaller 引擎 | 无额外参数 |
| 02 | 02 - hello_world - local |
使用 local 解压模式,文件释放到 exe 同级目录 |
--extract-mode local |
| 03 | 03 - hello_world - Nuitka |
使用 Nuitka 编译引擎打包 | --engine-mode nuitka |
| 04 | 04 - hello_world - PyOxidizer |
使用 PyOxidizer 引擎打包 | --engine-mode pyoxidizer |
| 05 | 05 - hello_world - icon |
自定义 exe 图标(.ico 格式) |
--icon "exe.ico" |
| 06 | 06 - hello_world - folder |
文件夹直接打包,跳过引擎构建,将指定文件夹封装为单文件 | --folder "hello_folder" --run "hello.exe" |
每个示例均提供
package.bat(Windows)和package.sh(Linux/Mac)两套构建脚本。
解压模式
PyInstallerEx 支持两种解压模式,通过 --extract-mode 参数控制:
| 模式 | 说明 | 解压路径 |
|---|---|---|
temp(默认) |
解压到系统临时目录 | %TEMP%\ex_{filename}_{md5} (Windows) 或 /tmp/ex_{filename}_{md5} (Linux) |
local |
解压到 exe 所在目录 | {exe所在目录}\{exe_stem}_release\ |
# 默认模式(解压到临时目录)
python -m PyInstallerEx your_script.py
# 本地模式(解压到 exe 所在目录)
python -m PyInstallerEx your_script.py --extract-mode local
使用场景:
- temp 模式:适合分发安装程序,避免污染用户目录
- local 模式:适合绿色便携版,所有文件集中在 exe 同级目录
打包引擎选择
PyInstallerEx 支持多种打包引擎,通过 --engine-mode 参数切换:
| 引擎 | 说明 | 依赖 |
|---|---|---|
pyinstaller(默认) |
使用 PyInstaller 打包 | PyInstaller |
nuitka |
使用 Nuitka 编译为 C 代码 | Nuitka, C编译器 |
pyoxidizer |
使用 PyOxidizer 打包 | PyOxidizer |
# 默认使用 PyInstaller
python -m PyInstallerEx your_script.py
# 使用 Nuitka
python -m PyInstallerEx your_script.py --engine-mode nuitka
# 使用 PyOxidizer
python -m PyInstallerEx your_script.py --engine-mode pyoxidizer
注意事项:
- Nuitka:需要安装 Nuitka (
pip install nuitka) 和 C 编译器(如 Visual Studio Build Tools) - PyOxidizer:需要单独安装 PyOxidizer,详见 PyOxidizer 文档
文件夹直接打包模式
使用 --folder 参数跳过 PyInstaller/Nuitka 等引擎打包流程,直接将指定文件夹压缩并附加到 Rust 启动器尾部,生成最终可执行文件。
# 将本地文件夹直接打包
python -m PyInstallerEx --folder ./my_app
# 指定输出文件名
python -m PyInstallerEx --folder ./my_app -n MyApp
# 指定解压后运行的主程序入口
python -m PyInstallerEx --folder ./my_app --run my_app.exe
# 指定运行子目录中的程序
python -m PyInstallerEx --folder ./my_app --run bin/start.exe
参数说明:
| 参数 | 说明 |
|---|---|
--folder <path> |
指定要打包的本地文件夹路径(与 script 互斥) |
--run <entry> |
指定解压后运行的主程序文件名或相对路径(写入配置 main 字段) |
注意事项:
--folder与位置参数script互斥,不能同时使用--folder指定的路径必须存在且为有效目录- 不指定
--run时,默认以文件夹名作为主程序名(Windows 自动添加.exe后缀) - 支持与其他参数组合使用,如
--icon、--extract-mode、--cfg等
使用场景:
- 已有编译好的程序目录,只需封装为单文件安装器
- 打包非 Python 项目(如 Node.js、Go 等编译产物)
- 需要精确控制打包内容,跳过引擎构建步骤
自定义图标
使用 --icon 参数为生成的可执行文件添加图标:
# 使用自定义图标(必须是 .ico 格式)
python -m PyInstallerEx your_script.py --icon my_icon.ico
# 使用默认图标(如果存在 src/PyInstallerEx/logo.ico)
python -m PyInstallerEx your_script.py
重要提示:
- ⚠️ 图标文件必须是
.ico格式,不支持.png、.jpg等其他格式 - ⚠️ 如果指定的图标文件不存在或格式不正确,会输出警告并跳过图标设置
- 💡 可以使用在线工具将 PNG/JPG 转换为 ICO 格式(如 https://convertio.co/png-ico/)
技术说明:
- Windows 平台图标设置方式:PyInstallerEx 使用
win32api.UpdateResourceAPI 在合并 ZIP 数据之前对纯启动器 exe 设置图标,避免破坏附加的 ZIP 数据和配置 JSON - 自动检测与嵌入:打包时自动检测图标参数,使用 pywin32 库直接修改 PE 文件的 RT_ICON 和 RT_GROUP_ICON 资源段
- ICO 文件格式解析:严格按照 Windows ICO 格式规范解析图像入口(
BBBBHHII格式),提取原始 DIB 图像数据写入资源段
🛠 开发
从源码构建
# 开发测试安装
pip install -e .
# 使用传统setup.py构建包
python setup.py sdist bdist_wheel
# 构建Rust启动器
./build_launchers.sh # Linux/Mac
build_launchers.bat # Windows
测试
# 运行测试套件
python test/test_rust_launcher.py
# 测试打包
python -m PyInstallerEx test/test_script.py --cfg test/test_config.json
# 运行生成的可执行文件
test/test_script.exe # Windows
./test/test_script # Linux/Mac
📁 项目文件结构
py-installer-ex/
├── bin/ # 预编译的启动器
│ ├── launcher_windows.exe # Windows 启动器 (64-bit)
│ ├── launcher_linux_x86 # Linux x86 启动器 (64-bit)
│ └── launcher_linux_arm # Linux ARM 启动器 (64-bit)
├── src/
│ ├── PyInstallerEx/ # Python 主程序
│ │ ├── __init__.py
│ │ ├── __main__.py # CLI入口点
│ │ ├── PyInstallerEx.py # 主模块
│ │ ├── core/
│ │ │ ├── config.py # 配置管理
│ │ │ └── packager.py # 打包逻辑
│ │ └── utils/
│ │ ├── compression.py # 压缩工具
│ │ ├── file_utils.py # 文件操作
│ │ ├── logging.py # 日志处理
│ │ └── system_utils.py # 系统检测
│ └── launcher/ # Rust 启动器源码
│ ├── src/main.rs # 启动器主程序
│ ├── Cargo.toml # Cargo配置
│ └── Cargo.lock
├── script/ # 安装和构建脚本
│ ├── install.bat # Windows 安装脚本
│ ├── build_launchers.bat # Windows 启动器构建
│ └── build_launchers.sh # Linux/Mac 启动器构建
├── test/ # 测试用例
│ ├── test_script.py
│ ├── test_config.json
│ ├── test_rust_launcher.py
│ └── test_python27_compatibility.py
├── build_launchers.bat # 启动器构建脚本(Windows)
├── build_launchers.sh # 启动器构建脚本(Linux/Mac)
├── pyproject.toml
├── setup.py
└── README.md
🔧 常见问题
Q: 找不到 launcher_windows.exe?
A: 确保 bin/ 目录下存在该文件。如果不存在:
- 检查是否从 Git 克隆时遗漏了
bin/目录 - 或运行
script\build_launchers.bat重新构建(需要安装 Rust)
Q: Python 版本要求?
A:
- 最低支持: Python 2.7
- 推荐使用: Python 3.8+
Q: linux 版本要求?
A:
- 最低支持: CentOS-9
- 推荐使用: CentOS-9 以上版本
Q: 需要安装 Rust 吗?
A:
- 不需要: 项目已包含预编译的启动器 (
bin/launcher_windows.exe) - 需要: 仅当你想修改或重新构建启动器时
Q: 如何清理虚拟环境?
A:
# Windows
rmdir /s /q .venv
# Linux/Mac
rm -rf .venv
Q: PowerShell 无法激活虚拟环境?
A: 执行以下命令后重试:
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
🔄 CI/CD 集成
在 CI/CD 环境中,可以使用环境变量跳过交互提示:
# 设置环境变量跳过交互确认
set CI=true
# 运行安装脚本
script\install.bat
📊 测试结果
- ✅ 打包流程测试通过
- ✅ 生成的安装器可正常执行
- ✅ 跨平台启动器编译成功
- ✅ 配置系统工作正常
- ✅ 错误处理机制完善
✅ 已完成的功能
1. 核心打包功能
- ✅ PyInstaller集成:使用
--onedir模式创建完整的应用程序目录 - ✅ 配置系统:JSON格式的配置文件支持
- ✅ ZIP压缩:将应用程序目录压缩为ZIP文件
- ✅ 二进制合并:将Rust启动器与ZIP文件合并为最终可执行文件
2. Rust启动器实现
- ✅ 跨平台支持:Windows、Linux x86、Linux ARM
- ✅ 智能安装:首次运行自动提取,后续运行复用已安装版本
- ✅ 配置解析:从可执行文件中读取和处理配置信息
- ✅ 临时目录管理:自动管理临时文件和清理
3. 文件夹直接打包
- ✅
--folder参数:跳过引擎构建,直接将指定文件夹压缩打包 - ✅
--run参数:自定义解压后运行的主程序入口 - ✅ 互斥校验:
--folder与script位置参数互斥处理
4. 项目结构完善
- ✅ 模块化设计:清晰的代码组织结构
- ✅ 错误处理:完善的异常处理和日志记录
- ✅ 构建脚本:自动化编译和测试脚本
- ✅ 文档完整:详细的使用说明和API文档
🔧 技术栈
- Python 2.7+ / 3.x: 主要开发语言
- PyInstaller >= 3.2.1: 应用程序打包基础
- Rust (edition 2021): 启动器开发语言(serde/serde_json、md5、flate2)
- JSON: 配置文件格式
- ZIP: 应用程序压缩格式
🔮 未来扩展方向
- GUI界面:添加图形化配置界面
- 数字签名:支持代码签名和安全验证
- 增量更新:实现应用程序的增量更新功能
- 更多平台:支持macOS等其他操作系统
- 插件系统:允许扩展自定义打包逻辑
更新日志
-
2026-07-03 V 0.1.10
- 新增
--folder参数,支持文件夹直接打包模式:跳过引擎构建,直接将指定文件夹压缩并附加到启动器 - 新增
--run参数,支持自定义解压后运行的主程序入口(配置main字段) - 新增参数互斥校验:
--folder与script位置参数不能同时使用 - 支持将非 Python 项目(如编译产物)封装为单文件安装器
- 新增
-
2026-07-02 V 0.1.9
- 新增
--engine-mode参数,支持选择打包引擎:pyinstaller(默认)、nuitka、pyoxidizer - 新增
--icon参数,支持自定义可执行文件图标(仅支持.ico格式) - 增强图标参数校验:检查文件是否存在、验证文件格式,无效时输出警告
- 新增 ZIP 数据 MD5 完整性校验:打包时计算 ZIP 数据的 MD5 哈希值并写入配置,运行时 Rust 启动器自动校验,防止数据损坏
- 更新 Nuitka 示例脚本,添加
--engine-mode nuitka参数
- 新增
-
2026-07-01 V 0.1.8
- 新增
--extract-mode参数,支持选择解压到系统临时目录(temp)或 exe 所在目录(local) - 修复相对路径下
output_dir为空导致的打包失败问题
- 新增
-
2026-06-30 V 0.1.7
- 将启动器从 Go 重写为 Rust,减小体积并提升性能
- 修复临时目录缓存问题,使用 exe 内容哈希标识版本,内容变化时自动重新解压
- 修复 PyInstaller 调用方式,使用
sys.executable -m PyInstaller替代直接命令 - 修复 Windows 终端下 emoji 字符编码导致的 GBK 输出错误
- 修复
setup.py中data_files引用不存在文件导致构建失败的问题
-
2025-11-07 V 0.1.6
- 修复了包分发中缺少启动器二进制文件的问题
- 改进了启动器文件搜索逻辑以支持包数据资源
- 增强了跨平台兼容性
-
2025-11-06 V 0.1.5
- 更新文档,包含最新版本信息和更新日志
-
2025-11-06 V 0.1.4
- 修复了Linux系统上找不到启动器文件的问题
- 改进了启动器文件搜索逻辑以支持通过data_files安装的文件
- 增强了跨平台兼容性
-
2025-11-06 V 0.1.3
- 修复了包分发问题,确保启动器二进制文件正确包含
- 改进了包构建和安装过程
-
2025-11-06 V 0.1.2
- 增强了缓存管理,自动清理旧目录
- 改进了配置处理,支持嵌入式配置读取
- 添加了对Linux ARM64平台的支持
- 添加了指定输出文件名的命令行选项
-
2025-10-23 V 0.1.1
- 初始版本,实现临时文件安装功能
- 完整的Rust启动器实现
- 跨平台支持(Windows、Linux x86/ARM)
- 配置系统
- 自动化构建脚本
📄 许可证
MIT许可证 - 详见 LICENSE 文件
项目状态:✅ 已完成核心功能开发 测试状态:✅ 功能测试通过 文档状态:✅ 文档完整可用
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyinstallerex-0.1.9.tar.gz.
File metadata
- Download URL: pyinstallerex-0.1.9.tar.gz
- Upload date:
- Size: 284.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
53a2f9a15b413512bea9848a2644adef169e667fba13e4cb92cb59e79be2e3f2
|
|
| MD5 |
0a3be40280c4954f9d5330ff14d341b0
|
|
| BLAKE2b-256 |
2afbc5ac4d653f4d87759bc3570560abf3973b226831b7c6c2bc3a834d522160
|
File details
Details for the file pyinstallerex-0.1.9-py3-none-any.whl.
File metadata
- Download URL: pyinstallerex-0.1.9-py3-none-any.whl
- Upload date:
- Size: 276.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2c1b3295f11f049cc47ba8736ce559302b58ad31f2ce980959d0a2d605efe2be
|
|
| MD5 |
2eb146e46f09934d1d1ecafc00c5688a
|
|
| BLAKE2b-256 |
7e5ea6a85b1f39e627545c5884a02829579de30f593c5e3e78a3b1ab67a22416
|