Pyinstaller将opencv从Windows 10分发到Windows< 10,缺少ucrt dlls api-ms-win-crt

时间:2017-09-26 00:51:10

标签: python windows opencv pyinstaller

我有一个使用OpenCV的Python 3.5 64位程序(Windows的tensorflow需要)。我用pyinstaller分发它。

我使用Windows 10构建了我的程序

/c/Python35/Scripts/pyinstaller -c DeepMeerkat.spec

在我的计算机上,.exe构建并运行完美。在任何其他非Windows 10计算机上

import cv2

返回

  

ImportError:DLL加载失败:找不到指定的模块。

我可以在pyInstaller thread上看到关于此问题的大量讨论, 但我不知道如何将其付诸实践。 Dependency walker说我缺少了许多DLL

api-ms-win-crt-**.dll

好的,从pyInstaller线程,我知道这些DLL存在

C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs

基于架构的多个子文件夹。

我尝试添加到我的.spec文件

pathex=["C:/Program Files (x86)/Windows Kits/10/Redist/ucrt/DLLs/"],

或者我的特定架构

pathex=["C:/Program Files (x86)/Windows Kits/10/Redist/ucrt/DLLs/arm"],

我认为这是建议的here

  

“为Windows 10和Windows安装Windows软件开发工具包(SDK)   展开.spec文件以包含所需的DLL,请参阅“分发   在上述链接中使用通用CRT的软件,   6号。“

这没有任何影响。我收到了数百个错误,比如

121472 WARNING: lib not found: api-ms-win-crt-runtime-l1-1-0.dll dependency of c:\python35\DLLs\_ssl.pyd

但我可以在这里看到DLL

C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\arm

enter image description here

然后我真的将posthoc复制到整个文件夹

cp -r "C:/Program Files (x86)/Windows Kits/10/Redist/ucrt/DLLs/" dist/Lib/

但目前尚不清楚如何将这些连接到.exe。显然,让pyInstaller事先知道是可取的。

我也试过

/c/Python35/Scripts/pyinstaller --path "C:/Program Files (x86)/Windows Kits/10/Redist/ucrt/DLLs/arm" -c DeepMeerkat.spec

它仍然没有找到它们

我也尝试将该文件夹添加到PATH。有什么想法吗?

3 个答案:

答案 0 :(得分:3)

如果您提供了规范文件,我可以看到发生了什么。从这里可能你不包括文件。

有两种方法可以从这里开始:

  1. 创建"一个"包含所有dll' s,pyd文件等的单个文件...结果是一个大型exe文件。
  2. 另一种方法是将它作为文件+文件夹填充dll文件等...你得到一个小的exe文件。
  3. 检查add binary (incl. dll) files here有关手动包含文件的pyinstaller文档。

    检查add data files here有关手动包含文件的pyinstaller文档。

    包含dll文件夹中的dll文件的示例规范文件。

    block_cipher = None a = Analysis(['minimal.py'], pathex = ['/Developer/PItests/minimal'], binaries = [ ( 'C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs', '.' ) ], datas = [ ('helpmod/help_data.txt', 'helpmod' ) ], hiddenimports = [], hookspath = None, runtime_hooks = None, excludes = None, cipher = block_cipher) pyz = PYZ(a.pure, a.zipped_data, cipher = block_cipher) exe = EXE(pyz,... ) coll = COLLECT(...)

答案 1 :(得分:1)

我自己需要这样做,但还没有。当我这样做时,我会尝试发布完整的解决方案。同时......

我认为您可能必须明确要求将其包含在内而不是仅扩展搜索路径。

https://pythonhosted.org/PyInstaller/spec-files.html#adding-binary-files

可能使用他们提到的Tree类来为您收集所有文件。

https://pythonhosted.org/PyInstaller/advanced-topics.html#the-tree-class

答案 2 :(得分:1)

我见过PyInstaller和Py2exe无法无数次攻击dll。就个人而言,我将它们的批量或bash用于包装,原因有很多,可以扩展它们的功能。从逻辑上讲,我看到了一个将它们包装在py脚本中的论据......

无论如何,通过包装器脚本将依赖项复制到安装包中可能更容易,而不是与之斗争。

通常,当你尝试运行它缺少的东西时,你会得到一个dll丢失的错误。手动将每一个添加到目录中,注意您需要自己包含的内容。然后编写脚本。