【发布时间】:2011-02-21 07:44:00
【问题描述】:
有没有办法为使用 DllImport 导入的给定程序集指定要搜索的路径?
[DllImport("MyDll.dll")]
static extern void Func();
这将在应用程序目录和 PATH 环境变量中搜索 dll。但有时 dll 会放在其他地方。是否可以在 app.config 或 manifest 文件中指定此信息以避免动态加载和动态调用?
【问题讨论】:
有没有办法为使用 DllImport 导入的给定程序集指定要搜索的路径?
[DllImport("MyDll.dll")]
static extern void Func();
这将在应用程序目录和 PATH 环境变量中搜索 dll。但有时 dll 会放在其他地方。是否可以在 app.config 或 manifest 文件中指定此信息以避免动态加载和动态调用?
【问题讨论】:
在您第一次调用导入的函数之前,使用您的附加 DLL 路径调用 SetDllDirectory。
P/Invoke 签名:
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetDllDirectory(string lpPathName);
要设置多个额外的 DLL 搜索路径,请修改 PATH 环境变量,例如:
static void AddEnvironmentPaths(string[] paths)
{
string path = Environment.GetEnvironmentVariable("PATH") ?? string.Empty;
path += ";" + string.Join(";", paths);
Environment.SetEnvironmentVariable("PATH", path);
}
有更多关于 DLL 搜索顺序的信息here on MSDN。
更新 2013/07/30:
以上使用Path.PathSeparator的更新版本:
static void AddEnvironmentPaths(IEnumerable<string> paths)
{
var path = new[] { Environment.GetEnvironmentVariable("PATH") ?? string.Empty };
string newPath = string.Join(Path.PathSeparator.ToString(), path.Concat(paths));
Environment.SetEnvironmentVariable("PATH", newPath);
}
【讨论】:
Path.PathSeparator
在第一次调用导入的函数之前,尝试使用您的附加 DLL 路径调用 AddDllDirectory。
如果您的 Windows 版本低于 8,您将需要安装 this patch,它使用 Windows 7、2008 R2、2008 和 Vista 缺少的 AddDllDirectory 函数扩展了 API(虽然没有针对 XP 的补丁)。
【讨论】:
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern int AddDllDirectory(string lpPathName);
这可能有用DefaultDllImportSearchPathsAttribute Class
例如
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.UserDirectories)]
还请注意,您也可以使用AddDllDirectory,这样您就不会搞砸已经存在的任何东西:
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AddDllDirectory(string path);
【讨论】:
.\Properties\AssemblyInfo.cs 文件中,其中. 是项目目录。它可能必须在任何 namespace 声明之外,或者这就是我遇到它或自己编写它时一直存在的地方。