6

我正在使用该[DllImport]属性将本机 DLL 导入我的应用程序,但它正在加载的 DLL 不在本地 bin 文件夹中。它是从系统上的其他地方加载的,但我不知道在哪里。

它适用于我的开发机器,但不适用于干净的机器。

我启用了 Fusion 日志记录,并且只显示了托管程序集。

我已经使用 Sysinternals Process Explorer 转储了该进程,这告诉我它在其中,C:\Windows\System32但我在 Windows Explorer 中看不到该文件。

值得注意的是,我运行的是 64 位 Windows 7,但 DLL 仅支持 x86,所以我不得不强制我的应用程序是 x86。是否有某种重定向会改变 x86 文件的加载位置?

DllImport 是一个定制的 Silicon Labs USB 驱动程序。[DllImport("SiUSBXp.dll")]

我还使用命令提示符dir si*在 System32 文件夹中进行了操作,但该文件不存在。

4

4 回答 4

4

文件系统重定向器将启动:

%windir%\System32 目录是为 64 位应用程序保留的。大多数 DLL 文件名在创建 64 位版本的 DLL 时没有更改,因此 32 位版本的 DLL 存储在不同的目录中。WOW64 通过使用文件系统重定向器隐藏了这种差异。

在大多数情况下,每当 32 位应用程序尝试访问 %windir%\System32 时,访问都会重定向到 %windir%\SysWOW64。

因此,即使该进程认为它从 加载 DLL System32,它也可能从 加载SysWOW64是的,这些数字与您期望的不同。

于 2012-12-19T10:39:46.627 回答
2

DllImport 背后的实际源代码在这里:

https://github.com/gbarnett/shared-source-cli-2.0/blob/master/clr/src/vm/dllimport.cpp

如您所见,它首先尝试在 .Net 的内部缓存中查找非托管库。

如果失败,但指定了绝对路径,它将使用该路径加载库。

如果未指定绝对路径,它将在以下位置查找:

1) 包含包含 DllImport 的程序集的清单文件的文件夹。

2) Assembly.CodeBase 中指定的文件夹。

3) LoadLibraryExW 看起来的所有地方。

如果一切都失败了,它会尝试将其解释为“文件名,程序集名”。

然后它将库添加到其内部缓存中。

于 2014-11-03T08:31:18.273 回答
1

您想阅读这个 - LoadLibrary 函数,并且从那里,您还想阅读这个Dynamic Link Library Search Order

注意 - 这些与本机 Win32 API 相关,但它是由[DllImport]属性使用的 API。

该文件可能没有显示在资源管理器中,因为您需要打开显示所有文件 - 许多常见[DllImport]指令(例如kernel32)针对 Win32 DLL,它们被归类为操作系统文件,因此默认情况下是隐藏的。

于 2012-12-19T10:28:59.017 回答
1

DLLImport通过以下路径搜索:

  1. 当前加载的 DLL(如果已经加载,则无需搜索文件)
  2. 当前进程的可执行模块目录
  3. 当前目录。
  4. “系统”目录。(即 c:\Windows\System32)
  5. “Windows”目录。(即 c:\Windows)
  6. PATH 环境变量中列出的目录。
于 2012-12-19T10:29:19.340 回答