将pyinstaller打包为exe文件
1 安装pyinstaller
# 我的版本较高
pip install pyinstaller==6.1.0
2 打包命令
(1)使用命令打包
# 打包命令
# 参数说明:
# -i 表示设置的exe文件的图标
# -D 表示安装程序打包为目录(推荐), -F 表示安装程序打包为一个exe包文件
# -w 表示关闭应用启动时的黑色窗口
pyinstaller -i E:/temp/favicon.png -D -w D:\\1_projects\\pycharm\\test\\main.py
(2)使用.spec文件打包
使用命令第一次打包后,会自动生成该文件,第一次以后可以进行修改后打包。
pyinstaller main.spec
main.spec文件
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['D:\\\\1_projects\\\\pycharm\\\\test\\\\main.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=["pyannote.audio", "pyannote.audio.models","pyannote.audio.models.embedding","pyannote.audio.models.segmentation","pyannote.audio.models.blocks"],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='main',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
# 控制显示黑色窗口,False不显示黑色窗口
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon=['E:\\temp\\favicon.png'],
)
coll = COLLECT(
exe,
a.binaries,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='main',
)
3 出现的问题
3.1 问题DistributionNotFound
问题
pkg_resources.DistributionNotFound: The 'rich' distribution was not found and is required by the application
解决方法
在Python的依赖包”PyInstaller\hooks“目录下,创建”hook-ctypes.macholib.py“文件,文件内容如下:
# hook-ctypes.macholib.py文件
from PyInstaller.utils.hooks import copy_metadata
datas = copy_metadata('rich')
3.2 问题FileNotFoundError
问题
FileNotFoundError: [WinError 3] 系统找不到指定的路径。: 'E:\\temp\\dist\\main\\_internal\\speechbrain\\utils'
解决方法
注意pyinstaller的版本,不同的版本打包后的目录不一样。
(1)如果是Python依赖包,在Python的依赖包目录下,找到speechbrain包,复制到pyinstaller打包后的于exe文件同级的_internal
目录下即可。
(2)如果是工程的配置文件,将配置文件复制到_internal
目录下即可。
(3)如果工程中的图片不显示,将相关的图片复制到_internal
目录下即可。
3.3 问题ModuleNotFoundError
问题
ModuleNotFoundError: No module named 'pyannote.audio.models'
解决方法
(1)在使用命令打包的时候,使用–hidden-import参数,追加依赖包;
(2)推荐,使用.spec文件打包,在文件中的”hiddenimports“参数中追加依赖包,我的文件如下;
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
……
hiddenimports=["pyannote.audio", "pyannote.audio.models","pyannote.audio.models.embedding","pyannote.audio.models.segmentation","pyannote.audio.models.blocks"],
……
)
……
3.4 问题输出和Logging报错
--noconsole
或-w
模式时,它会自动将您的sys.stdout
和sys.stderr
设置为None。所以如果你的代码或库使用日志或写消息到这些流中的任何一个,它将导致一个错误。通常类似于NoneType object has no attribute write
。如果这是您收到的错误,那么您需要做的就是将sys.stdout
和sys.stderr
重定向到一个新的流,如打开的文件或io缓冲区。
将下面的脚本放在Logging或者print执行前即可。
import io
import sys
stream = io.StringIO()
sys.stdout = stream
sys.stderr = stream