指定DllImport在.NET中的搜索路径

问题描述 投票:0回答:4

有没有办法指定使用 DllImport 导入的给定程序集的搜索路径?

[DllImport("MyDll.dll")]
static extern void Func();

这将在应用程序目录和 PATH 环境变量中搜索 dll。但有时 dll 会被放置在其他地方。是否可以在app.config或manifest文件中指定这些信息以避免动态加载和动态调用?

.net dllimport
4个回答
71
投票

在第一次调用导入的函数之前,使用附加的 DLL 路径调用

SetDllDirectory

P/调用签名:

[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 搜索顺序的更多信息请参见 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); }
    

15
投票
在首次调用导入函数之前,尝试使用其他 DLL 路径调用

AddDllDirectory



如果您的 Windows 版本低于 8,则需要安装

此补丁,它通过 Windows 7、2008 R2、2008 和 Vista 缺少的 AddDllDirectory

 功能扩展了 API(但 XP 没有补丁) .


7
投票
这可能有用

DefaultDllImportSearchPathsAttribute 类 例如

[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.UserDirectories)]
另请注意,您也可以使用 

AddDllDirectory,这样您就不会搞砸已经存在的任何内容:

[StructLayout(LayoutKind.Sequential)] struct DllDirectoryCookie { private nint value; } [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] static extern DllDirectoryCookie AddDllDirectory(string path);
并清理干净:

[StructLayout(LayoutKind.Sequential)] struct BOOL { int value; /*...*/ operator bool(BOOL x) => x.value != 0; } [DllImport("kernel32.dll", SetLastError = true)] static extern BOOL RemoveDllDirectory(DllDirectoryCookie cookie);
    

0
投票
我认为这个问题,即使是更古老的问题,仍然是相当相关的,无论框架目前如何发展,也许“最好”的方法是使用框架本身。任何感兴趣的人,我建议在任何本机/外部库上使用“DefaultDllImportSearchPaths”属性。这是一个示例:

[DefaultDllImportSearchPaths(DllImportSearchPath.SafeDirectories)] [DllImport("Netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] static extern int NetServerGetInfo(string serverName, int level, out IntPtr pSERVER_INFO_XXX);
    
© www.soinside.com 2019 - 2024. All rights reserved.