与其他答案的建议相反,使用
Dllimport属性仍然是正确的方法。
老实说,我不明白为什么您不能像世界上其他所有人一样,并指定DLL 的 相对
路径。是的,在不同人的计算机上,应用程序的安装路径会有所不同,但这基本上是部署的通用规则。该
Dllimport机制的设计考虑到这一点。
实际上,它甚至
Dllimport无法解决问题。无论您是否使用方便的托管包装程序(P / Invoke
marshaller只是调用
LoadLibrary),它都是控制事情的本机Win32
DLL加载规则。这些规则在这里详细列出,但是重要的规则在这里摘录:
在系统搜索DLL之前,它会检查以下内容:
- 如果内存中已经加载了具有相同模块名称的DLL,则系统将使用已加载的DLL,无论它位于哪个目录中。系统都不会搜索该DLL。
*如果该DLL在运行该应用程序的Windows版本的已知DLL列表中,则系统使用其已知DLL的副本(以及已知DLL的从属DLL,如果有的话)。系统不搜索DLL。如果
SafeDllSearchMode启用(默认),则搜索顺序如下:
- 从中加载应用程序的目录。
- 系统目录。使用该
GetSystemDirectory函数获取此目录的路径。- 16位系统目录。没有获取该目录路径的函数,但会对其进行搜索。
- Windows目录。使用该
GetWindowsDirectory函数获取此目录的路径。- 当前目录。
6.PATH环境变量中列出的目录。请注意,这不包括“应用程序路径”注册表项指定的每个应用程序路径。计算DLL搜索路径时不使用“应用程序路径”键。
因此,除非您为DLL命名与系统DLL相同(除非在任何情况下都不应该这样做),否则默认搜索顺序将开始在加载应用程序的目录中查找。如果在安装过程中将DLL放在此处,则会找到它。如果仅使用相对路径,所有复杂的问题都会消失。
写就好了:
[Dllimport("MyAppDll.dll")] // relative path; just give the DLL's namestatic extern bool MyGreatFunction(int myFirstParam, int mySecondParam);但是,如果由于某种原因该方法 不起作用
,并且您需要强制应用程序在DLL的其他目录中查找,则可以使用
SetDllDirectory函数修改默认的搜索路径。
请注意,根据文档:
调用后
SetDllDirectory,标准DLL搜索路径为:
- 从中加载应用程序的目录。
lpPathName参数指定的目录。- 系统目录。使用该
GetSystemDirectory函数获取此目录的路径。- 16位系统目录。没有获取该目录路径的函数,但会对其进行搜索。
- Windows目录。使用该
GetWindowsDirectory函数获取此目录的路径。 PATH环境变量中列出的目录。
因此,只要您在第一次调用从DLL导入的函数之前调用此函数,就可以修改用于定位DLL的默认搜索路径。当然,这样做的好处是您可以将 动态
值传递给在运行时计算的该函数。使用
Dllimport属性是不可能的,因此您仍将在此处使用相对路径(仅DLL的名称),并依靠新的搜索顺序为您找到它。
您必须P /调用此功能。声明看起来像这样:
[Dllimport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]static extern bool SetDllDirectory(string lpPathName);

![如何在运行时指定[DllImport]路径? 如何在运行时指定[DllImport]路径?](http://www.mshxw.com/aiimages/31/442726.png)
