DllImport在搜索DLL时是否遵循SafeDllSearchMode?

3

假设我想在某个DLL中进行典型的非托管调用:

[DllImport("unmanaged.dll")]
static extern int SomeFuncion1(int parm);

DllImportAttribute是否根据注册表中SafeDllSearchMode的设置搜索DLL?我在MSDN上没有找到任何指示搜索顺序是否遵循“标准搜索顺序”的内容。


1
顺便提一下,从 MSDN 上来看 -> 您可以提供完整或相对路径。如果不提供路径,则 DLL 必须在运行时的当前路径中,除非 DLL 是通过其他方式加载的。但是请注意,如果 DLL 被移动,使用完全限定路径可能会引入不准确性。 - http://msdn.microsoft.com/zh-cn/library/system.runtime.interopservices.dllimportattribute.value(VS.90).aspx。 - Ahmad
2个回答

3
是的,P/Invoke marshaller只是使用LoadLibrary()。它会观察设置。在SO帖子中无法证明它实际上是否这样做,除非你自己尝试,我得出结论是没有合理的替代方法。LoadLibrary完全属于“难”API函数类别。
顺便说一下,它永远不会使用您的[ DllImport ]声明找到该DLL。非托管DLL只有一个路径,它们没有托管程序集属性,例如版本、文化、pkt。如果这实际上是具有这些属性的托管程序集,则使用Assembly.Load()加载它。但是,调用静态函数会很困难,CLR不支持这样做,每个方法都必须属于一个类。
使用Dumpbin.exe /exports命令查找该DLL导出的内容。

2

好吧,我有些急躁并且自己回答了这个问题,但是 Hans 在这期间已经回答了。

首先,我创建了一个测试工具:


注:本文中的“it技术”未明确指定,因此无法确定具体的翻译术语,请您谅解。
[DllImport("SomeDllThatDoesntExist.dll")]
public static extern void Test();

static void Main()
{
     string currentWorkingDirectory = Directory.GetCurrentDirectory();
     Console.WriteLine(currentWorkingDirectory);
     Directory.SetCurrentDirectory("E:\\foobar");
     currentWorkingDirectory = Directory.GetCurrentDirectory();
     Console.WriteLine(currentWorkingDirectory);
     // Call method in DLL we know doesn't exist.
     Test();
}

然后我使用Procmon进行监测,Test()调用的搜索路径顺序如下:

  1. 执行目录
  2. System32目录
  3. 系统目录(16位)
  4. Windows目录
  5. 当前目录(“E:\foobar”)
  6. 所有我的$PATH目录

这表明它遵循“安全”搜索顺序,因为当前目录是#5而不是#2,如果SafeDllSearchMode被禁用,则会是#2。然后我添加了 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SafeDllSearchMode注册表值并将其设置为1(禁用),再次运行我的测试工具。搜索路径仍然相同。我不知道是否弄错了添加注册表键,但我真正想知道的唯一重要的事情是,默认情况下是否遵循了“安全”搜索顺序路径-这意味着当前目录不是顺序中的#2。


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