Pyinstaller在从Windows 10分发opencv到Windows <10时缺少ucrt dlls api-ms-win-crt。

11

我有一个 Python 3.5 64 位程序(tensorflow for Windows 所需),其中使用了 OpenCV。我正在使用 pyinstaller 进行分发。

该程序是在 Windows 10 上构建的。

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

在我的电脑上,.exe文件可以完美地构建和运行。但在任何其他非Windows 10的计算机上

上面的 "On" 是指 "关于" 或 "就......而言" 的引导词,没有独立的翻译。

import cv2

返回

导入错误:DLL 加载失败:找不到指定的模块。

我在pyInstaller线程上看到了大量关于这个问题的讨论,但是我不知道如何实践。Dependency walker 显示我缺少一些 DLLs。

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"],

这正是我认为所建议的这里

"安装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

所以,我字面上地后来复制了整个文件夹

在此输入图片描述

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中。 有任何想法吗?


我即使找到了dll文件,也无法让它正常工作。"解决方案"就是使用我的安装程序在用户的计算机上安装vcredist_x86.exe,这样问题就得到了解决,尽管它们看起来是相同的。可能是用户计算机上的路径问题。 - bw4sz
你使用的是哪个版本的PyInstaller?上个月发布的3.3版本修复了在Windows 10上针对Python >=3.5的一些问题。 - jthetzel
我按照维护者的指示在Github上使用了dev分支。 - bw4sz
3个回答

3
如果您能提供规范文件,我就能看到出了什么问题。从这里来看,可能是您没有包含文件。
以下有两种方法可供选择:
1.创建“一个”包含所有dll、pyd文件等的单个文件...作为结果的大型exe文件。
2.另一种方法是将其作为文件+填充有dll文件等的文件夹...您会得到一个小的exe文件。
请查看在此处添加二进制(包括dll)文件关于手动包含文件的pyinstaller文档。
请查看在此处添加数据文件关于手动包含文件的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(...)

这段代码涉及到编程方面,其中的变量和函数需要在程序中使用。其中`block_cipher`是一个密码算法,而其他变量是用于分析、打包和收集Python应用程序的参数。

“binaries”或“pathex”似乎在这里有问题。至少它不能解决“lib not found: api-ms-win-crt-stdio-l1-1-0.dll”的问题... - Gaetan
@Gaetan:我不太确定你所说的“二进制文件”或“pathex”在这里似乎是错的。。。文件损坏、丢失等问题,你的情况到底是怎么了?如果这是一个新的问题...请发布一个新问题,并将您的评论包含在那里。如果与OP的文件路径有关,则我只有提供的信息。因此,它被发布为一个“示例”,大致说明应该如何,正如所述;-) - ZF007
我找到了让它工作的方法。这里的“二进制文件”部分实际上没有任何作用,因为查找机器C运行时DLL的循环使用了pathex。解决方案是添加ucrt目录的相对路径(x86和x64都要),循环将只获取正确的那些。我已经直接将这些小型dll复制到我的项目树中,最多只有5 MB,所以不需要费心安装完整的Windows 10 SDK来检索这些dll。 - Gaetan

1

1
我见过PyInstaller和Py2exe在捕捉dll方面失败了无数次。个人而言,出于许多原因,我将它们的使用包装在批处理或bash中以扩展它们的功能。逻辑上,我认为将它们包装在py脚本中是有道理的... 无论如何,通过包装脚本将依赖项复制到安装包中可能会更容易,而不是与此作斗争。通常,当尝试运行缺失某些内容的东西时,您会遇到缺少dll的错误。手动将每个文件添加到目录中,并注意需要自己包含的内容。然后编写脚本。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接