我亲自进行了测试,使用的是Win10 64位系统,搭配Python 3.9.13以及PyInstaller 5.13.0,在此过程中,遇到了封装完成后exe双击没有反应的情况,还碰到了缺少DLL的问题,……
我亲自进行了测试,使用的是Win10 64位系统,搭配Python 3.9.13以及PyInstaller 5.13.0,在此过程中,遇到了封装完成后exe双击没有反应的情况,还碰到了缺少DLL的问题,并且出现过提示“failed to execute script”这种经典大坑,新手只要按照步骤一步步去操作,便能够轻松地避开这类常见问题。
第一步 先确认系统架构和依赖版本号
去展开命令行,去执行python -c”import platform; print(platform.architecture())” 以瞅瞅本机Python到底是32位还是64位。这一步骤绝对得跟要打包的目标操作系统位数全然相同,就好似你开发机是64位Python,然而客户机则是32位系统,那样打包而出的exe极有可能直接出现报错而无法启动。随后,去执行pip list,以此列出全部已安装的包,着重留意numpy、pandas、opencv-python这类带有C扩展的库,这些库的版本号直接决定了dll能否被正确加载。
【新手躲避陷阱】,出现的报错状况是,exe启动之后,马上就闪退了,把cmd打开,将exe拖进去运行,提示“ImportError: DLL load failed while importing…”。核心缘由在于,pyinstaller进行打包操作时,默认状况下不会自行囊括C扩展所依赖的dll,迅速的解决方式为,在打包命令之后添加 –collect-all numpy ,又或者精确到 –add-data”C:Python39Libsite -packagesnumpy.libs;numpy.libs” ,将整个.libs目录强行纳入进去。
第二步 用虚拟环境隔离依赖并生成spec文件
构建洁净的虚拟环境是防止封装兼容性校验出现失败状况的最为有效的方式。运行 python -m venv venv_pack ,而后执行 venv_packScriptsactivate ,于虚拟环境当中仅安装你的脚本实际进行 import的库 ,切勿安装任何多余的包。接着去执行,pyi – makescript your_script.py,以此来生成spec文件,随后打开spec文件,寻觅到binaries = []这一行,接着手动去填入,需要额外绑定的dll路径,就像binaries = [( ‘C:/Windows/System32/vcruntime140.dll’, ‘.’ )]这样。
【针对新手的避坑提示】存在这样一种状况,即报错所呈现的一种具体表现是,打包的这个过程是正常的,然而呢,当这个exe在旁人的电脑上进行运行的时候,却出现了提示,它提示说出了这么一番表示无法启动这个程序的话语,原因在于计算机之中丢失了VCRUNTIME140.dll这个文件。其核心缘由在于,微软 VC++运行库未伴随 exe 文件一同分发,而能够迅速加以解决的办法,便是在 spec 文件之中添加上 –add-data”C:WindowsSystem32vcruntime140.dll;.” ,或者直接促使客户去安装 Microsoft Visual C++ 2015 – 2022 Redistributable,这乃是关键参数的最佳推举值,其缘由是该运行库囊括了几乎所有被封装依赖的底层 C 运行时。
第三步 使用UPX压缩并指定完整打包路径
下达打包指令之际,添入两个关键参数:pyinstaller -F -w –upXdirC:upX – 4.2.4 – win64your_script.spec。-F造就单文件然而兼容性校验更为严格,-w隐匿控制台窗口适宜于GUI程式。需要特别留意的是,倘若你在脚本之中使用了相对路径去读取资源文件,那么在打包之后极有可能出现找不到路径进而致使崩溃的情况。这里存在两种实操方案并作对比区分,一种情况是方案A通过使用–onefile单exe 的方式来进行操作,其具备的优点在于以便于分发,然而其缺点却是启动速度较为缓慢同时易于被杀毒软件错误地进行报警提示;另一种情况是方案B采用–onedir文件夹模式来操作,它所拥有的优点是启动速度快、兼容性比较高而且报错定位便利,但其缺点在于需要将整个文件夹发送给客户。要是客户是那种对技术一窍不通的小白,那就推荐方案B,原因在于报错之后,你能够直接通过远程去查看文件夹当中的日志文件。
初涉者需避开的陷阱是,高频出现的完整报错呈现为“Failed to execute script main”,通常会伴随一个产生却无具体错误讯息的弹出框。完整的、能实现一站式解决的流程如下:第一步,将打包命令里的 -w 去除掉,用采用 -c 模式再次进行打包运作,如此一来 exe 就会留存控制台输出;第二步,于客户机之上借助 cmd 去运行 exe,进而复制报错涉及的内容;第三步,依据报错所涉及的行号来定位至你所编写的脚本具体代码,大多数情形下,系 os.getcwd() 获取的路径存在错误之举,应改用 sys._MEIPASS 和 os.path.dirname(sys.executable) 二者的组合去获取实际运行的路径。
这个办法针对于纯Python脚本,在依赖简单且不存在硬件绑定的场景当中,效果颇为不错,然而要是运用了pygame、pytorch、tensorflow这类带有硬件加速驱动(CUDA、DirectX)的库,又或者脚本中调用了注册表、COM组件、驱动级API,那么上述步骤依旧存在可能会失败的情况。替代的方案是借助Nuitka编译成C扩展之后再进行封装,要不然就直接给客户提供源码以及环境安装脚本,以此来规避单exe的兼容性魔咒。
微信扫一扫
还没有评论呢,快来抢沙发~