说明
本文主要针对于多文件打包,单文件打包不在本博客范围内。
大型项目打包可参考本文。
经本人测试,在win10系统下打包后的软件,无法在win7下运行。结合以往项目经验,若有跨平台需求,需要在不同平台下分别打包生成对应平台下的可执行文件,方可分发至不同平台用户。
环境:
Python版本 | 3.7 |
---|---|
开发工具 | PySide2 |
系统 | Win10 64位 |
部分命令简介
–distpath
: 打包到哪个目录下
-w: 指定生成 GUI 软件,也就是运行时不打开控制台
-c: 运行时打开控制台
-i : 指定打包后可执行文件的图标
–clean: 在构建之前清理PyInstaller缓存并删除临时文件
-D: 创建包含可执行文件的单文件夹包,同时会有一大堆依赖的 dll 文件,这是默认选项
-F: 只生成一个 .exe 文件,如果项目比较小的话可以用这个,但比较大的话就不推荐
步骤
- 打包多个文件时,首先运行命令:
pyinstaller.exe -D main.py
。其中,main.py文件是程序入口文件,其他文件也可,主要是为了生成spec文件 - 删除dist、build文件夹(暂时用不到)
- 修改spec文件
- a=Analysis()中,第一个参数为项目中所有python文件列表(需指明文件路径),文件较多是可通过代码罗列,参考下面示例
- pathex为项目绝对路径,eq:
'D:\\work\\project\\
- binaries为项目中使用到的非python包,为二元tuple列表:[(文件所在路径,打包后存放文件夹名称)]
- datas为项目中使用到的所有数据文件(文件所在路径,为二元tuple列表:[打包后存放文件夹名称)],文件夹名称为文件所在路径相对于项目绝对路径的相对路径。
eq:('D:\\work\\project\\ui\\icons\\imgs\\*.png', 'ui\\icons\\imgs')
表示将imgs
下的所有png
图片打包后存放至ui\\icons\\imgs
路径下 - EXE()中,console=False决定是否在运行软件时弹出命令行窗口;name='softwarename’表示打包后的软件名称
- 保存
spec
文件,在命令行窗口输入命令:pyinstaller.exe -F main.spec
- 在当前目录下,会生成build、dist文件夹,可删除build文件夹,在dist文件夹中,有以softwarename命名的文件夹,打开该文件夹,有对应的
exe
文件,双击运行无报错说明打包成功。
报错
- 报错
utf-8
解码错误
在命令行窗口输入如下命令,指定编码:
chcp 65001
fail to execute script pyi_rth_pkgres
pip uninstall pyinstaller
pip install https://github.com/pyinstaller/pyinstaller/archive/develop.zip
类似的错误也有可能是在excludes
中将不该排除的包排除了,从而因缺失相关依赖导致无法运行。
spec文件示例
# -*- mode: python -*-
import os
block_cipher = None
p = ['D:\\work\\project\\ui\\dialog\\', 'D:\\work\\project\\ui\\customUI\\', 'D:\\work\\project\\modules\\']
pyfiles = ['D:\\work\\project\\main.py', 'D:\\work\\project\\ui\\main_ui.py']
for pi in p:
for fn in os.listdir(pi):
if fn.split('.')[-1] == 'py':
pyfiles.append(pi + fn)
a = Analysis(pyfiles,
pathex=['D:\\work\\project'], # absolute path
binaries=[('D:\\work\\project\\modules\\module1.cp37-win_amd64.pyd', 'pyd-modules'), ('D:\\work\\project\\modules\\module2.cp37-win_amd64.pyd', 'pyd-modules'), ('D:\\work\\project\\modules\\module3.cp37-win_amd64.pyd', 'pyd-modules')],
datas=[('D:\\work\\project\\ui\\icons\\imgs\\*.png', 'ui\\icons\\imgs'),('D:\\work\\project\\ui\\icons\\fugueicon\\*.png', 'ui\\icons\\fugueicon\\'),('D:\\work\\project\\ui\\icons\\flaticon\\*.png', 'ui\\icons\\flaticon')],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='softwarename',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False # whether show a cmd window
)
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='softwarename')