目标:在什么都没装的win7上运行成功
win10
python3.7.10
shapely(从https://www.lfd.uci.edu/~gohlke/pythonlibs/#shapely 安装)
pyqt5 opencv-python imgaug pyclipper lmdb pyzbar pyinstaller tornado IPython ipykernel sip
paddle(安装方式如下)
conda install paddlepaddle --channel https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/Paddle/
如下,从tools/infer/MainUI.py启动
打包命令
pyinstaller MainUI.spec
MainUI.spec
相比于自动生成spec,多了把需要的文件传到对应的地方
# -*- mode: python -*-
# _*_ coding:utf-8 _*_
import os
import sys
block_cipher = None
# 当前路径
cur_path=os.path.abspath('.')
# 模型路径
INFERENCE_PATH = 'inference'
# 打包的py文件
py_files=[os.path.join('tools','infer','MainUI.py')]
# 需要的数据
datas=[
(os.path.join('tools','infer','*.txt'),'tools\\infer'), # dict
(os.path.join('logo','yan.ico'), 'logo'),
(os.path.join('tools','infer','*.ttf'),'tools\\infer')
]
# 添加模型
for directory in os.listdir('inference'):
if os.path.isdir(os.path.join(INFERENCE_PATH,directory)):
datas.append((os.path.join(INFERENCE_PATH,directory,'*'),os.path.join(INFERENCE_PATH,directory)))
a = Analysis(py_files,
pathex=[cur_path],
binaries=[
],
datas=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='MainUI',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
icon=os.path.join('logo','yan.ico'))
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='MainUI')
在本机运行
重点研究下面这句
Failed to load dynlib/dll 'E:\\PyCharmProject\\OCR\\dist\\MainUI\\pyzbar\\libiconv.dll'. Most probably this dynlib/dll was not found when the application was frozen
解决方法
将python的pyzbar下的两个dll复制到exe所在的目录的pyzbar下
相比于上次,在binaries下添加了pyzbar的两个dll
# -*- mode: python -*-
# _*_ coding:utf-8 _*_
import os
import sys
block_cipher = None
# 当前路径
cur_path=os.path.abspath('.')
# python所在的路径
python_path=sys.path[4]
# 第三方包路径
packages_path=os.path.join(python_path,'Lib','site-packages')
# pyzbar 路径
pyzbar=os.path.join(packages_path,'pyzbar')
# 模型路径
INFERENCE_PATH = 'inference'
# py_files=list(filter(lambda x:os.path.splitext(x)[-1]=='.py',os.listdir(cur_path)))
# 打包的py文件
py_files=[os.path.join('tools','infer','MainUI.py')]
# 需要的数据
datas=[
(os.path.join('tools','infer','*.txt'),'tools\\infer'), # dict
(os.path.join('logo','yan.ico'), 'logo'),
(os.path.join('tools','infer','*.ttf'),'tools\\infer')
]
# 添加模型
for directory in os.listdir('inference'):
if os.path.isdir(os.path.join(INFERENCE_PATH,directory)):
datas.append((os.path.join(INFERENCE_PATH,directory,'*'),os.path.join(INFERENCE_PATH,directory)))
a = Analysis(py_files,
pathex=[cur_path],
binaries=[
(os.path.join(pyzbar,'*.dll'),'pyzbar'), # pyzbar的lib
],
datas=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='MainUI',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
icon=os.path.join('logo','yan.ico'))
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='MainUI')
在本机运行
解决方法
将python的paddle下的libs下的dll复制到exe所在的目录的paddle/libs下
这次相比于上次,添加了paddle缺失的dll
# -*- mode: python -*-
# _*_ coding:utf-8 _*_
import os
import sys
block_cipher = None
# 当前路径
cur_path=os.path.abspath('.')
# python所在的路径
python_path=sys.path[4]
# 第三方包路径
packages_path=os.path.join(python_path,'Lib','site-packages')
# paddle路径
paddle_path=os.path.join(packages_path,'paddle')
# pyzbar 路径
pyzbar=os.path.join(packages_path,'pyzbar')
# 模型路径
INFERENCE_PATH = 'inference'
# py_files=list(filter(lambda x:os.path.splitext(x)[-1]=='.py',os.listdir(cur_path)))
# 打包的py文件
py_files=[os.path.join('tools','infer','MainUI.py')]
# 需要的数据
datas=[
(os.path.join('tools','infer','*.txt'),'tools\\infer'), # dict
(os.path.join('logo','yan.ico'), 'logo'),
(os.path.join('tools','infer','*.ttf'),'tools\\infer')
]
# 添加模型
for directory in os.listdir('inference'):
if os.path.isdir(os.path.join(INFERENCE_PATH,directory)):
datas.append((os.path.join(INFERENCE_PATH,directory,'*'),os.path.join(INFERENCE_PATH,directory)))
a = Analysis(py_files,
pathex=[cur_path],
binaries=[
(os.path.join(pyzbar,'*.dll'),'pyzbar'), # pyzbar的lib
(os.path.join(paddle_path,'libs','*'),'paddle\\libs'), # paddle的lib
],
datas=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='MainUI',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
icon=os.path.join('logo','yan.ico'))
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='MainUI')
在本机上运行
但是发现启动了老半天都没起来
打开任务管理器,发现一堆的exe
解决方法
参考https://gitee.com/lazytech_group/scr2txt
修改python的paddle下的dataset下的image.py
将
import six
import numpy as np
# FIXME(minqiyang): this is an ugly fix for the numpy bug reported here
# https://github.com/numpy/numpy/issues/12497
if six.PY3:
import subprocess
import sys
import_cv2_proc = subprocess.Popen(
[sys.executable, "-c", "import cv2"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
out, err = import_cv2_proc.communicate()
retcode = import_cv2_proc.poll()
if retcode != 0:
cv2 = None
else:
import cv2
else:
try:
import cv2
except ImportError:
cv2 = None
改成
import six
import numpy as np
# FIXME(minqiyang): this is an ugly fix for the numpy bug reported here
# https://github.com/numpy/numpy/issues/12497
# if six.PY3:
# import subprocess
# import sys
# import_cv2_proc = subprocess.Popen(
# [sys.executable, "-c", "import cv2"],
# stdout=subprocess.PIPE,
# stderr=subprocess.PIPE)
# out, err = import_cv2_proc.communicate()
# retcode = import_cv2_proc.poll()
# if retcode != 0:
# cv2 = None
# else:
# import cv2
# else:
# try:
# import cv2
# except ImportError:
# cv2 = None
try:
import cv2
except ImportError:
cv2 = None
spec与上次一样
在win7虚拟机上运行
提示缺少MSVCR120.dll
并且出现了第一次打包中缺少的dll,明明就在那里了
解决方法
在exe所在的目录下,添加如下dll(如果本机运行程序没有问题,说明自己电脑有这些dll)
均可以在C:\Windows\System32下找到,
如果没有,可以考虑下面这个链接
http://www.winwin7.com/soft/xtbd-216.html
mfc120.dll
mfc120chs.dll
mfc120cht.dll
mfc120deu.dll
mfc120enu.dll
mfc120esn.dll
mfc120fra.dll
mfc120ita.dll
mfc120jpn.dll
mfc120kor.dll
mfc120rus.dll
mfc120u.dll
mfcm120.dll
mfcm120u.dll
msvcp120.dll
msvcr120.dll
vcamp120.dll
vccorlib120.dll
vcomp120.dll
终于成功了
题外话
之前用的3.8.10打包,遇到的问题更多,除了上述问题还有
1.
ModuleNotFoundError: No module named 'skimage.filters.rank.core_cy_3d'
解决方法
在spec的hiddenimports中添加
hiddenimports=['skimage.filters.rank.core_cy_3d']
这个算简单的
2.add_dll_directory报错
这个东西在win10虚拟机上是没有问题的,但是win7
这个是我目前唯一找不到解决方案的
1.
如果提示
Failed to load dynlib/dll 'xxxxxx\\xxxxx.dll'. Most probably this dynlib/dll was not found when the application was frozen
优先考虑把对应包的dll复制到对应位置,如果不行,就考虑把
http://www.winwin7.com/soft/xtbd-216.html里安装的dll加进去
2.
ModuleNotFoundError: No module named 'xxx'
在spec的hiddenImport中添加'xxx'
3.
如果你的程序半天没启动,并且打开任务管理器发现有好多个,可以考虑检查一下的你报有没有用到subprocess这个模块
4.add_dll_directory
win10上不会有问题,但是win7上会出现这个
考虑降版本到3.7.10及以下