安装pyinstaller
pycharm 左下角,打开包管理器
左上角输入要搜索的包
右上角点击安装
安装完后在 File - Settings - Projecxt:XXX 中设置 Python Interpreter
设置系统环境变量
打包时报错:找不到pyinstaller命令
pyinstaller : 无法将“pyinstaller”项识别为 cmdlet、函数、脚本文件或可运行程序的名称:
需要设置系统环境变量后,在当前路径才会认识这个命令。
将鼠标放到pyinstaller上面,会出现包存放的路径,
存放包路径:C:\Users\Administrator\AppData\Roaming\Python\Python310\site-packages
Scripts路径:C:\Users\Administrator\AppData\Roaming\Python\Python310\Scripts
找到与存放包同级的文件Scripts,添加的系统变量环境是同级的Scripts!!!!!
找到包的存放路劲只是为了方便找到Scripts文件,需要添加到环境变量的是Scripts路径。(这只是我的路径,与你们不一样)
我的电脑 - 属性 - 高级系统设置
改了系统变量后,记得重启ide
设置图标
只能是ico文件才能设置为图标,png和jpg格式是不接受的,我这里给一个免费的png和jpg格式转ico格式的网站,可以更具自己的需求设置图标大小,转化网址点击下方链接
https://png2icojs.com/zh/
https://app.xunjiepdf.com/img2icon/
输入结束后点击回车等待完成即可
控制台命令格式
1.进入Terminal控制台进行编辑
2.转入对应路径(可看情况忽略)
ps:如果你的文件本身就位于项目下,可忽略此步骤
3.控制台内输入代码
输入:pyinstaller -F -w -i 图标路径(.ico) 运行文件名
例:
Pyinstaller -F py_word.py 打包exe
Pyinstaller -F -w py_word.py 不带控制台的打包
Pyinstaller -F -w -i chengzi.ico py_word.py 打包指定exe图标打包
-w是指程序启动的时候不会打开命令行。如果不加-w的参数,就会有黑洞洞的控制台窗口出来。比如在刚才的脚本里我加一行print('Hello World!'),那么就不要放-w参数了,不然运行会报错,毕竟Hello World!需要在命令行里打印出来。此外,-w参数在GUI界面时非常有用。
最后的-i chengzi.ico就是指设置自己的图标图案,因为默认打包图片是下图这样的。这个参数也可以写成--icon=chengzi.ico
1.打包成功的显示
创建成功后,会生成以下文件(前两个文件夹可以直接删掉):
dist文件夹中的exe即为我们所需要的可执行文件,可以打成压缩包发给朋友试试!
2.找到exe文件的路径
3.完成
引用丢失问题
我查找了大部分运行exe文件没有执行的情况,并且对应我自己的实际情况我发现几乎80%失败的原因都是没有将相应文件引用进来。
第一种方法:在自己的虚拟环境中找到该模块的dll,手动复制粘贴到打包后目录即可:
若项目中有文件用到了相对路径,需要把那些用到的文件再拷贝一份放到dist目录下。
ps:对于其他文件的引用也是类似的解决方法
如果你的程序中有图片等资源,是需要根据程序中的相对路径加入到dist文件中,也要在.exe同目录中加入images的文件夹(图片资源)
如果原.py程序使用了图片等素材,并且添加图片是相对路径(同一个文件夹下可以不使用绝对路径),打包文件后,需要将图片等素材拷贝一份放在打包后的文件夹下,否则运行.exe程序会找不到图片素材。
如果原.py程序使用图片添加的是绝对路径,在本地电脑上运行时可能不会发现错误。但是你将打包后的文件发给另一台机器,运行.exe程序会报错,大概意思是“根据你写的绝对路径找不到图片等素材”,即使你在文件夹下拷贝了素材,但是绝对路径也是错误的,所以,最好使用上一种方法。
2)打包的主文件问题
只能指定一个要打包的模块,也就是启动模块
发布后,可执行文件执行路径不能有中文(最好也不要有空格)
启动执行的文件中不要有下面这种判断,否则可执行文件执行会没有任何效果
if __name__=='__main__':
将exe放到其他机子上运行,弹出“找不到msvcr100.dll“ ,手动将”msvcr100.dll“拷贝到dist目录下即可
3)养成良好习惯
写代码的时候应当养成良好的习惯,用什么函数导什么函数,不要上来就import整个库,最后你会发现你一个100KB的代码打包出来有500MB,全是库
第二种方法:修改spec文件的时候设置好导入位置,打包时会自动识别
打包过程找不到自己自建模块如
ModuleNotFoundError: No module named 'core'
可以将模块添加到datas里注意复制后的名字('core','core')最好是原名(个人经验)。
还可以将自己的模块直接复制到site-packages 下面,再打包。
打包成功却不能正确执行,进程无法阻塞,.exe一直在循环。
这是因为在调用某些模块的时候,也是进程,而在多进程中,你程序中的进程不会被阻塞,而一直循环起进程。用下面方法去解决,注意下面代码要放在代码最开始在import 模块之前。
from multiprocessing import freeze_support
freeze_support()
多层树形依赖
特殊情况dll都打包进exe了,还会有这类DLL not found issue
- 可能是由于该dll本身也有依赖,因此需要将dll在当前开发环境的依赖包,同样放到目标环境exe目录中(或直接打包进exe),才可以正确执行
否则就算将源码迁移到另一台机器,运行时也是报同样的错误,因为该dll依赖在目标机器系统内不支持
通过 dependencywalker 工具来查找该Dll的依赖包:
- Dependency Walker (depends.exe) Home Page
下载后,打开depends.exe工具,将相关dll导入,即可找到所有依赖,
例如我这里使用的dll有4个依赖:
然后在 C:\Windows\System32 下,依次找到所依赖的库文件
复制到exe执行目录,即可正常运行。
为了优化解决办法,可以把所有依赖的dll都打包进exe中,方便在目标PC运行,
可参考: Python通过PyInstaller 将DLL文件直接打包进exe,
打包后运行闪退
我遇到这个情况,不打包运行的好好的,打包后一运行就闪退,
不要用双击模式运行,可以用cmd或者powershell运行exe,这样闪退后打印出报错信息
报错缺少模块,这种情况很可能是没有在虚拟环境内部进行打包,详见以下文章描述,严格执行打包流程。
https://www.cnblogs.com/new-june/p/11968037.html
解决pyinstaller打包涉及uiautomation截图时出现的dll找不到的错误_pyinstaller打包缺少dll_游一尘的博客-CSDN博客
包体压缩
刚刚生成的exe实在太大了,300多M的软件程序想用微信传一下都费劲。
我也试过很多方法,比如:修改spec文件自定义打包、pipenv 虚拟环境、使用开源的upx压缩等等,但是往往要么过程比较麻烦,要么成功率不高(压缩成不成功全看脸)。
而我要分享的,是自己一直在用的,最简单且成功率极高的方法——conda创建虚拟环境。
Python打包为什么大
在压缩打包之前,先简单说一下为什么Python打包过大?
Python打包exe,不但体积大而且运行奇慢。解释型语言大都是这个样子,只不过Python尤其突出。要解决大而慢,只能用编译型语言,如C,C++,甚至VB都好很多,体积最小的是汇编。[1]
此外,还有知乎大佬说是因为“Anaconda里内置了很多库,打包的时候打包了很多不必要的模块进去,要用纯净的Python来打包。”
所以我们可以模拟一个新环境,其中只安装我们本次打包所必要的工具包即可。
那最适合的就是——虚拟环境了!
虚拟环境
Python创建虚拟环境的方法有很多,而我是个Anaconda忠实用户,如果你跟我一样,那就简单了。(大家也可以使用Virtualenv、Pipenv来设置虚拟环境,善用搜索,方法大同小异)
先记几个命令,很简单
conda create -n 虚拟环境名字 python==3.6 #创建虚拟环境
conda activate 虚拟环境名字 #激活虚拟环境
conda deactivate #退出虚拟环境
从开始菜单运行“Anaconda Prompt”,出现的界面输入创建虚拟环境的指令。成功创建了一个名字为aotu,且基于python版本3.6的虚拟环境。
制作Installer安装文件
用Inno SetUp将exe文件制作成安装包
使用Inno SetUp制作安装包_鱼生艰难啊的博客-CSDN博客