PyInstaller打包exe可执行文件详细教程


写本文的初衷是,自己在使用PyInstaller过程中踩了很多坑,花了很多时间搜了很多教程,最后才实现了打包的exe软件能够在自己以及其他人的Windows PC上都正常运行。

代码是一个交互式的医学影像标注软件,GUI通过PyQt 5,深度学习算法基于PyTorch实现,调用了基于TensorFlow的crop_and_resize实现的一个外部包RoIAlign。

大致描述一下要打包的代码包含哪些元素:

  1. 代码及代码中import的包(PyInstaller会自动打包进来)
  2. 外部包RoIAlign(手动修改.spec文件)
  3. 模型的checkpoint.pth.tar(手动修改.spec文件)

描述一下踩到的坑,希望可以帮到看到这篇文章的人。

  1. checkpoint没有被自动打包,需手动修改spec文件,然后通过spec重新进行打包。
  2. 外部包RoIAlign没有被自动打包,需手动修改spec文件,然后通过spec重新进行打包。
  3. spec的属性在其生成时已经被决定,所以在运行spec重新打包时,即使改变了参数,如-D变为-F,是无效的。
  4. 在自己的PC上可以运行,但在别人的PC上运行就闪退。

我这边的开发环境是:

  • Window 10
  • Anaconda3
  • Python 3.6.10
  • PyTorch 1.2.0

PyInstaller

基本上

PyInstaller安装

pip安装

pip install pyinstaller

pip升级

pip install --upgrade pyinstaller

PyInstaller使用

PyInstaller的使用还是非常简单的,假设主程序代码是main.py, 只需要使用以下代码即可实现。

pyinstaller main.py

官方文档可以点击 链接

当然可以按照按照自己的需求修改参数,这里列一下常用参数对应的含义。

参数含义
-h, --help显示PyInstaller帮助信息并退出
-v, --version显示PyInstaller版本信息
–clean在打包前清除PyInstaller缓存和临时文件
-D, --onedir创建一个包含可执行文件的文件夹包(默认)
-F, --onefile创建一个可执行的文件包
-n, --name更改打包生成的文件的文件名
-c, --console, --nowindowed打开用于标准I / O的控制台窗口(默认)。 在Windows上,如果第一个脚本是“ .pyw”文件,则此选项无效。
-w, – windowed, --noconsoleWindows和Mac OS X:不提供标准I / O的控制台窗口。 在Mac OS X上,这也会触发构建OS X .app捆绑软件。 在Windows上,如果第一个脚本是“ .pyw”文件,则将设置此选项。 在* NIX系统中,此选项被忽略。

其他的一些参数可以点击 链接 查询。

其中,What to bundle,where to bundle部分,更建议通过spec文件来修改。
在这里插入图片描述
这边有个小建议,就是尽量不是用-F这个指令。将全部文件打包到一个可执行exe中,很容易遇到问题,且不容易debug。在用PyInstaller时,先使用-D,将文件打包到一个文件夹里,后面我再介绍用什么文件将这个文件夹转化为一个exe,易调试,简单,且可以压缩文件夹的大小。

需要调试时,用

pyinstaller -D -c main.py

这样在运行exe时,控制台窗口会弹出,方便进行调试。

调试完成,用

pyinstaller -D -w main.py

这样在运行exe时,控制台窗口不会弹出,方便使用。

如何让PyInstaller把额外的文件打包进来

上面提到我的应用里需要把深度学习模型的权重文件,就是checkpoint.pth.tar一起打包起来。

假设将打包文件放置在release文件夹中,则按照上面的操作,release文件夹中将包含以下3个文件/文件夹:
build
release
main.spec
此时我们需要修改Main.spec文件。

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

a = Analysis(['..\\main.py'],
             pathex=['E:\\release'],
             binaries=[],
             datas=[],
             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='Controller',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          console=False )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               upx_exclude=[],
               name='Controller')

修改Analysis中的datas即可。将要添加的文件的路径和添加后的路径给出即可。

a = Analysis(['..\\main.py'],
             pathex=['E:\\release'],
             binaries=[],
             datas=[('..\\checkpoint.pth.tar','checkpoint.pth.tar')],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)

然后重新用main.spec打包一次。前面说过了,用.spec打包的话,更改参数无效。因此只需要

pyinstaller main.spec

即可。

完成后,在dist文件夹中,应该能找到checkpoint.pth.tar文件了。

当然了,更简单的方法,就是直接拷贝到dist里。。。也没问题

如何让PyInstaller把外部包打包进来

上面提到,我的代码中使用了一个基于TensorFlow的crop_and_resize实现的一个外部包RoIAlign
GitHub链接:https://github.com/longcw/RoIAlign.pytorch
当然现在PyTorch官方也提供了RoIAlign层,可以直接使用。如果直接使用官方的RoIAlign层,这没有这个问题了。

下面我们还是以使用了外部包的情况来说明。

尽管roi_align已经出现在了dist文件夹中,但我在运行中依然遇到了找不到roi_align-0.0.2-py3.6-win-amd64.egg的报错,我是通过以下方式来解决,让需要的包和依赖文件都被添加到dist文件夹中。

**核心还是根据报错信息添加对应的依赖文件。**这边只是一个示例

依然是需要修改.spec文件。

# -*- mode: python ; coding: utf-8 -*-

import sys
sys.setrecursionlimit(5000)
from os import path
site_packages = next(p for p in sys.path if 'site-packages' in p)
block_cipher = None

a = Analysis(['..\\main.py'],
             pathex=['E:\\release'],
             binaries=[],
             datas=[('..\\checkpoint.pth.tar','checkpoint.pth.tar') ,(path.join(site_packages,'roi_align-0.0.2-py3.6-win-amd64.egg'),'roi_align-0.0.2-py3.6-win-amd64.egg')],
             hiddenimports=['roi_align','crop_and_resize.py','crop_and_resize_cpu','scipy.special.cython_special'],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)

解决自己的PC可以运行打包好的exe,别人PC却无法运行的问题

这个问题困扰了我好久。后来发现是问题出在缺少 Visual C++ Redistributable。解决方法是:

  1. 首先,请先确认 Windows 操作系统为 32 位还是 64 位(可参考该链接进行查询);

  2. 确定系统版本之后
    a) 32 位系统:"vc_redist.x86.exe”进行配置;
    b) 64 位系统:“vc_redist.x64.exe”进行配置;

微软官方有提供这两个安装包,网上搜索 一下也有很多。

将打包生成的文件夹转成一个单一exe

上面也说了,直接用-F可以时间打包成单一exe,但不推荐这样操作。
我这边使用的是Enigma Virtual Box,下载链接
在这里插入图片描述
免费版的即可。
运行Enigma Virtual Box
在这里插入图片描述在Enter Input File Name中选择dist中的exe文件main.exe,在Enter Output File Name中选择输出的路径和文件名,默认文件名是main_boxed.exe。
然后点击左下角Add…,选择Add Folder Recursive, 然后选择dist文件夹,确定即可。
在这里插入图片描述
需要进行压缩的话,选择右下角File Option然后勾选File Compress即可。
-》等待压缩完成,完成后就得到一个单一exe了。

  • 3
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值