首页 > 解决方案 > Python 2.7 无法从 cmd.exe Windows 10 加载 DLL(VC2017 内置)

问题描述

再会!我刚刚遇到了一个非常棘手的问题,我几乎无法解释和解决。

我有一个在 VC 2017 中编译的 dll。这个 dll 基本上是一个 python 模块:SWIG 包装器用于创建接口。因此,在给定的文件夹中,我有以下文件:

文件 test_lib.py 是 SWIG 生成的接口。

我的“load.py”脚本:

from test_lib import *

我在 shell 中执行的命令:

python.exe load.py

测试

如果我以普通用户身份在 cmd.exe 中运行此命令,则会收到以下错误:

Traceback (most recent call last):
  File "load.py", line 1, in <module>
    from test_lib import *
  File "test_lib.py", line 28, in <module>
    TestLib = swig_import_helper()
  File "test_lib.py", line 24, in swig_import_helper
    _mod = imp.load_module('TestLib', fp, pathname, description)
ImportError: DLL load failed: The specified module could not be found.

似乎 Windows 或 Python 都无法加载该模块。我用 Dependency Walker 检查了 dll 依赖项,一切似乎都很好。

现在奇怪的事情开始了。

如果我在具有管理权限的 cmd.exe 中执行相同的命令,它就可以工作!

如果我以普通用户的身份在 Powershell 中执行相同的命令,它会再次运行!


分析

我使用了 Process Monitor 工具并分析了这三个调用中的每一个。

  1. cmd.exe + 普通用户

  2. cmd.exe + admin 或 powershell.exe + 普通用户

是的,cmd+admin 和 powershell+regular 表现出相同的行为。您可能会看到,在命令 QueryAllInformationFile 获得 BUFFER OVERFLOW 状态之后的所有三个调用中,Windows 开始在不同的位置搜索库(为什么???)。

在检查了 2 个替代路径(C:\MyCompany\Project\Project\Project\Project\Bin\Win32\TestLib.pydC:\Project\Bin\Win32\TestLib.pyd)后的最后两个调用中,Windows运行回到初始位置C:\MyCompany\Project\Project\Project\bin\Win32\TestLib.pyd并最终开始加载 DLL。

但是,具有常规用户权限的 cmd.exe 的行为方式有所不同。Windows 尝试了一堆目录,它似乎最终终止了该过程,因为认为该库尚未找到。(为什么???

最后,如果我做了一个小技巧,除了它的原始位置之外,还将我的库复制到C:\MyCompany\Project\Project\Project\Project\Bin\Win32\TestLib.pyd cmd.exe 使用常规用户权限运行没有错误!这是荒唐的。


问题

  1. 这个调用到底发生了什么(cmd.exe + 普通用户)?

  2. 我该如何解决?

  3. 为什么 Windows 会尝试在这么多位置搜索我的库,尽管它从第一步开始就在最初指定的位置检测到它?

标签: pythonwindowsvisual-studiopowershellcmd

解决方案


推荐阅读