使用命令行发现丢失的模块(“DLL 加载失败”错误)
- 2025-02-11 09:51:00
- admin 原创
- 84
问题描述:
在 Windows 上,当我们尝试导入一个文件,并且找不到所依赖的.pyd
DLL时,我们会收到此回溯:.pyd
Traceback (most recent call last):
...
ImportError: DLL load failed: The specified module could not be found.
当这种情况发生时,通常人们必须借助于像Dependencies这样的图形工具来找出缺失模块的名称。
如何通过命令行获取丢失的模块名称?
背景:我们经常在 CI 中遇到此错误,通过 SSH 登录来找出丢失的模块名称会比通过 GUI 登录更容易。
解决方案 1:
首先,让我们选择一个具体的例子:NumPy的_multiarray_umath.pyd(来自Python 3.9(pc064*))。请注意,我将重复使用此控制台:
[cfati@CFATI-5510-0:e:WorkDevStackOverflowq074877580]> sopr.bat ### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ### [prompt]> [prompt]> "e:WorkDevVEnvspy_pc064_03.09_test0Scriptspython.exe" Python 3.9.9 (tags/v3.9.9:ccb0e6a, Nov 15 2021, 18:08:50) [MSC v.1929 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> >>> import os >>> >>> os.getpid() 12788 >>> >>> from numpy.core import _multiarray_umath as _mu >>> >>> _mu <module 'numpy.core._multiarray_umath' from 'e:\\Work\\Dev\\VEnvs\\py_pc064_03.09_test0\\lib\\site-packages\\numpy\\core\\_multiarray_umath.cp39-win_amd64.pyd'> >>> ^Z [prompt]> [prompt]> :: Backup %PATH% [prompt]> set _PATH=%PATH%
为了使事情尽可能通用,.pyd依赖于自定义.dll ( OpenBLAS ):
以下是上述( Python )过程的快照:
注意依赖的.dll的加载位置(我们(选定的).pyd下方两行)。
现在,回到问题:有很多工具可以做到这一点。
但需要指出的是,无论你使用什么工具,都(很可能)取决于PATH环境变量的内容(在第一张图片中,未找到依赖的.dll(和其他)。查看[MS.Learn]:动态链接库搜索顺序,了解有关.dll的更多详细信息。
需要注意的是,由于(某些)工具会生成大量输出,我将把它过滤掉(使用FindStr(Grep)等命令),只显示相关部分,以避免答案中充满垃圾。
1. [GitHub]: lucasg/Dependencies
除了您提到的GUI应用程序( DependenciesGui.exe )之外,还有一个命令行工具:Dependencies.exe:
[prompt]> [prompt]> :: Restore %PATH% [prompt]> set PATH=%_PATH% [prompt]> [prompt]> "f:Installpc064LucasGDependencyWalkerPolitistTexanVersionDependencies.exe" -h Dependencies.exe : command line tool for dumping dependencies and various utilities. Usage : Dependencies.exe [OPTIONS] <FILE> Options : -h -help : display this help -json : activate json output. -cache : load and use binary cache in order to prevent dll file locking. -depth : limit recursion depth when analysing loaded modules or dependency chain. Default value is infinite. -apisets : dump the system's ApiSet schema (api set dll -> host dll) -apisetsdll : dump the ApiSet schema from apisetschema <FILE> (api set dll -> host dll) -knowndll : dump all the system's known dlls (x86 and x64) -manifest : dump <FILE> embedded manifest, if it exists. -sxsentries : dump all of <FILE>'s sxs dependencies. -imports : dump <FILE> imports -exports : dump <FILE> exports -modules : dump <FILE> resolved modules -chain : dump <FILE> whole dependency chain [prompt]>
umpycore_multiarray_umath.cp39-win_amd64.pyd" | findstr "libopenblas"
[NOT_FOUND] libopenblas.FB5AE2TYXYH2IJRDKGDGQ3XBKLKTF43H.gfortran-win_amd64.dll :
[prompt]>
[prompt]> set PATH=%_PATH%;e:WorkDevVEnvspy_pc064_03.09_test0Libsite-packages
umpy.libs
[prompt]>
[prompt]> "f:Installpc064LucasGDependencyWalkerPolitistTexanVersionDependencies.exe" -modules "e:WorkDevVEnvspy_pc064_03.09_test0Libsite-packages
umpycore_multiarray_umath.cp39-win_amd64.pyd" | findstr "libopenblas"
[Environment] libopenblas.FB5AE2TYXYH2IJRDKGDGQ3XBKLKTF43H.gfortran-win_amd64.dll : e:WorkDevVEnvspy_pc064_03.09_test0Libsite-packages
umpy.libslibopenblas.FB5AE2TYXYH2IJRDKGDGQ3XBKLKTF43H.gfortran-win_amd64.dll
旁注 - 正如在[SO]:如何使用 ctypes 运行 fortran 脚本?(@CristiFati 的回答)中看到的,有时(由于某些我不知道的原因)它不显示导出(至少是GUI )。
2.依赖遍历器
虽然它不再被维护,但它是一个非常好的工具,在Dependencies之前它是我能找到的最好的工具。我还将它用于[SO]:如何构建 libjpeg 9b 的 DLL 版本?(@CristiFati 的回答)(在最后某处)。
缺点是它会将输出拆分到文件中,因此需要额外的步骤:
[prompt]> [prompt]> :: Restore %PATH% [prompt]> set PATH=%_PATH% [prompt]> [prompt]> dir /b [prompt]> [prompt]> :: Help not available in console (/? will open GUI) [prompt]>
umpycore_multiarray_umath.cp39-win_amd64.pyd"
[prompt]> type _mu0.txt | findstr -i "libopenblas"
[ ? ] LIBOPENBLAS.FB5AE2TYXYH2IJRDKGDGQ3XBKLKTF43H.GFORTRAN-WIN_AMD64.DLL
[ ? ] LIBOPENBLAS.FB5AE2TYXYH2IJRDKGDGQ3XBKLKTF43H.GFORTRAN-WIN_AMD64.DLL Error opening file. The system cannot find the file specified (2).
[prompt]>
[prompt]> set PATH=%_PATH%;e:WorkDevVEnvspy_pc064_03.09_test0Libsite-packages
umpy.libs
[prompt]>
[prompt]> "c:Installpc064DependsDependencyWalkerPolitistTexanVersiondepends.exe" /c /ot:_mu1.txt "e:WorkDevVEnvspy_pc064_03.09_test0Libsite-packages
umpycore_multiarray_umath.cp39-win_amd64.pyd"
[prompt]> type _mu1.txt | findstr -i "libopenblas"
[ 6] e:workdevenvspy_pc064_03.09_test0libsite-packages
umpy.libsLIBOPENBLAS.FB5AE2TYXYH2IJRDKGDGQ3XBKLKTF43H.GFORTRAN-WIN_AMD64.DLL
[ 6] e:workdevenvspy_pc064_03.09_test0libsite-packages
umpy.libsLIBOPENBLAS.FB5AE2TYXYH2IJRDKGDGQ3XBKLKTF43H.GFORTRAN-WIN_AMD64.DLL 2022/11/30 14:57 2022/11/20 00:44 35,695,412 A 0x0220BC27 0x0220BC27 x64 Console None 0x00000000622C0000 Unknown 0x01E88000 Not Loaded N/A N/A 0.0 2.30 4.0 5.2
3. [MS.Learn]: DUMPBIN 参考
VStudio的一部分。我仅将其列为参考,因为它可以显示.dll依赖项,但不能显示它们是否可以加载(如果可以,则从哪里加载):
[prompt]> [prompt]> :: Restore %PATH% [prompt]> set PATH=%_PATH% [prompt]> [prompt]> "c:Installpc032MicrosoftVisualStudioCommunity9VCAuxiliaryBuildcvarsall.bat" x64 > nul [prompt]>
umpycore_multiarray_umath.cp39-win_amd64.pyd"
Microsoft (R) COFF/PE Dumper Version 14.29.30147.0
Copyright (C) Microsoft Corporation. All rights reserved.Dump of file e:WorkDevVEnvspy_pc064_03.09_test0Libsite-packages
umpycore_multiarray_umath.cp39-win_amd64.pyd
File Type: DLL
Image has the following dependencies:
libopenblas.FB5AE2TYXYH2IJRDKGDGQ3XBKLKTF43H.gfortran-win_amd64.dll python39.dll KERNEL32.dll VCRUNTIME140.dll api-ms-win-crt-math-l1-1-0.dll api-ms-win-crt-heap-l1-1-0.dll api-ms-win-crt-stdio-l1-1-0.dll api-ms-win-crt-string-l1-1-0.dll api-ms-win-crt-environment-l1-1-0.dll api-ms-win-crt-runtime-l1-1-0.dll api-ms-win-crt-convert-l1-1-0.dll api-ms-win-crt-time-l1-1-0.dll api-ms-win-crt-utility-l1-1-0.dll api-ms-win-crt-locale-l1-1-0.dll
Summary
40000 .data 18000 .pdata 64000 .rdata 3000 .reloc 1000 .rsrc 1F3000 .text
4.Nix模拟器
调用[Man7]: LDD(1)。
我想这可能是一个最爱,因为它倾向于Nix世界(这类事情更容易),而且你还提到了SSH连接。
我将在MSYS2上举例说明,但其他系统(Cygwin,也许是MinGW,...)也可以实现同样的事情。
[cfati@cfati-5510-0:/e/Work/Dev/StackOverflow/q074877580]> ~/sopr.sh ### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ### [064bit prompt]> [064bit prompt]> uname -a MSYS_NT-10.0-19045 cfati-5510-0 3.4.3-dirty.x86_64 2022-12-19 20:20 UTC x86_64 Msys [064bit prompt]> [064bit prompt]> _PATH="${PATH}" [064bit prompt]> [064bit prompt]> ls "/e/Work/Dev/VEnvs/py_pc064_03.09_test0/Lib/site-packages/numpy/core/_multiarray_umath.cp39-win_amd64.pyd" /e/Work/Dev/VEnvs/py_pc064_03.09_test0/Lib/site-packages/numpy/core/_multiarray_umath.cp39-win_amd64.pyd [064bit prompt]> [064bit prompt]> ldd "/e/Work/Dev/VEnvs/py_pc064_03.09_test0/Lib/site-packages/numpy/core/_multiarray_umath.cp39-win_amd64.pyd" ldd: /e/Work/Dev/VEnvs/py_pc064_03.09_test0/Lib/site-packages/numpy/core/_multiarray_umath.cp39-win_amd64.pyd: Bad file descriptor [064bit prompt]> [064bit prompt]> # Change extension [064bit prompt]> cp "/e/Work/Dev/VEnvs/py_pc064_03.09_test0/Lib/site-packages/numpy/core/_multiarray_umath.cp39-win_amd64.pyd" ./_mu.dll [064bit prompt]> ls _mu.dll _mu0.txt _mu1.txt [064bit prompt]> file _mu.dll _mu.dll: PE32+ executable (DLL) (GUI) x86-64, for MS Windows [064bit prompt]> [064bit prompt]> ldd _mu.dll ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ff8ba930000) KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ff8ba320000) KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll (0x7ff8b8070000) msvcrt.dll => /c/WINDOWS/System32/msvcrt.dll (0x7ff8b8f40000) _mu.dll => /e/Work/Dev/StackOverflow/q074877580/_mu.dll (0x7ff86ab50000) ucrtbase.dll => /c/Windows/System32/ucrtbase.dll (0x7ff8b8840000) vcruntime140.dll => /c/Windows/System32/vcruntime140.dll (0x7ff8a0980000) libopenblas.FB5AE2TYXYH2IJRDKGDGQ3XBKLKTF43H.gfortran-win_amd64.dll => not found python39.dll => not found api-ms-win-crt-math-l1-1-0.dll => not found api-ms-win-crt-heap-l1-1-0.dll => not found api-ms-win-crt-stdio-l1-1-0.dll => not found api-ms-win-crt-string-l1-1-0.dll => not found api-ms-win-crt-environment-l1-1-0.dll => not found api-ms-win-crt-runtime-l1-1-0.dll => not found api-ms-win-crt-convert-l1-1-0.dll => not found api-ms-win-crt-time-l1-1-0.dll => not found api-ms-win-crt-utility-l1-1-0.dll => not found api-ms-win-crt-locale-l1-1-0.dll => not found [064bit prompt]> [064bit prompt]> PATH="${_PATH}:/e/Work/Dev/VEnvs/py_pc064_03.09_test0/Lib/site-packages/numpy/.libs" [064bit prompt]> [064bit prompt]> ldd _mu.dll ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ff8ba930000) KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ff8ba320000) KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll (0x7ff8b8070000) msvcrt.dll => /c/WINDOWS/System32/msvcrt.dll (0x7ff8b8f40000) _mu.dll => /e/Work/Dev/StackOverflow/q074877580/_mu.dll (0x7ff86ab50000) ucrtbase.dll => /c/Windows/System32/ucrtbase.dll (0x7ff8b8840000) vcruntime140.dll => /c/Windows/System32/vcruntime140.dll (0x7ff8a0980000) libopenblas.FB5AE2TYXYH2IJRDKGDGQ3XBKLKTF43H.gfortran-win_amd64.dll => /e/Work/Dev/VEnvs/py_pc064_03.09_test0/Lib/site-packages/numpy/.libs/libopenblas.FB5AE2TYXYH2IJRDKGDGQ3XBKLKTF43H.gfortran-win_amd64.dll (0x622c0000) user32.dll => /c/Windows/System32/user32.dll (0x7ff8b92f0000) win32u.dll => /c/Windows/System32/win32u.dll (0x7ff8b8940000) gdi32.dll => /c/Windows/System32/gdi32.dll (0x7ff8b94a0000) gdi32full.dll => /c/Windows/System32/gdi32full.dll (0x7ff8b8400000) msvcp_win.dll => /c/Windows/System32/msvcp_win.dll (0x7ff8b8610000) python39.dll => not found api-ms-win-crt-math-l1-1-0.dll => not found api-ms-win-crt-heap-l1-1-0.dll => not found api-ms-win-crt-stdio-l1-1-0.dll => not found api-ms-win-crt-string-l1-1-0.dll => not found api-ms-win-crt-environment-l1-1-0.dll => not found api-ms-win-crt-runtime-l1-1-0.dll => not found api-ms-win-crt-convert-l1-1-0.dll => not found api-ms-win-crt-time-l1-1-0.dll => not found api-ms-win-crt-utility-l1-1-0.dll => not found api-ms-win-crt-locale-l1-1-0.dll => not found
当然,可能还有更多我不知道的工具(或者涉及来自.NET的.dll )。
相关(或多或少):
[SO]:在 Python 中加载具有依赖项的 DLL(@CristiFati 的答案)
[SO]:如何检查 DLL 依赖性?
[SO]:C DLL 在 C++ 程序中加载,而不是在 python Ctypes 中加载(@MarkTolonen 的答案)
[SO]:ImportError:导入 _ctypes 时 DLL 加载失败:找不到指定的模块(@CristiFati 的回答)
[SO]:无法让 FontForge 作为模块导入自定义 Python 脚本(@CristiFati 的回答)
扫码咨询,免费领取项目管理大礼包!