打包报错记录

目标:在什么都没装的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启动

打包报错记录_第1张图片

打包命令

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')

在本机运行 

打包报错记录_第2张图片

重点研究下面这句

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下

打包报错记录_第3张图片

第二次打包 

 相比于上次,在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')

在本机运行

打包报错记录_第4张图片

解决方法

将python的paddle下的libs下的dll复制到exe所在的目录的paddle/libs下

打包报错记录_第5张图片

第三次打包

这次相比于上次,添加了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')

在本机上运行 

但是发现启动了老半天都没起来

打包报错记录_第6张图片

打开任务管理器,发现一堆的exe 

打包报错记录_第7张图片

解决方法

参考https://gitee.com/lazytech_group/scr2txt

修改python的paddle下的dataset下的image.py

打包报错记录_第8张图片

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

打包报错记录_第9张图片

并且出现了第一次打包中缺少的dll,明明就在那里了

打包报错记录_第10张图片

解决方法

在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报错

打包报错记录_第11张图片

这个东西在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及以下

你可能感兴趣的:(安装与配置)