【问题标题】:Specify the search path for DllImport in .NET在 .NET 中指定 DllImport 的搜索路径
【发布时间】:2011-02-21 07:44:00
【问题描述】:

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

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

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

【问题讨论】:

    标签: .net dllimport


    【解决方案1】:

    在您第一次调用导入的函数之前,使用您的附加 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);
    }
    

    【讨论】:

    • 谢谢,从静态构造函数调用 SetDllDirectory 后效果很好。
    • AFAIK,不幸的是这并不能解决多个额外搜索目录的问题。
    • @Stefan,请参阅我修改后的添加多个目录的答案。
    • 谢谢。我认为这是我们能得到的最好的。
    • 你最好使用Path.PathSeparator
    【解决方案2】:

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

    如果您的 Windows 版本低于 8,您将需要安装 this patch,它使用 Windows 7、2008 R2、2008 和 Vista 缺少的 AddDllDirectory 函数扩展了 API(虽然没有针对 XP 的补丁)。

    【讨论】:

    • 听起来不错,但 DllImport 应该是什么样子?
    • 这是一个更好的解决方案,因为与公认的答案不同,当应用程序作为 Microsoft Store 应用程序(UWP 或打包的 Win32 应用程序作为 UWP)运行时,此 API 也能正常工作。 Microsoft Store 应用程序接受的答案将失败,因为操作系统将当前环境列表阻止到 UWP 应用程序。所以 DllImport 将无法看到带有 dll 的路径。要在 C# 中使用它,您可以通过以下方式复制导入此 API:[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern int AddDllDirectory(string lpPathName);
    【解决方案3】:

    这可能有用DefaultDllImportSearchPathsAttribute Class
    例如

    [assembly: DefaultDllImportSearchPaths(DllImportSearchPath.UserDirectories)]
    

    还请注意,您也可以使用AddDllDirectory,这样您就不会搞砸已经存在的任何东西:

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool AddDllDirectory(string path);
    

    【讨论】:

    • 你能说明在哪里放置 [assembly:... 属性吗?
    • 我相信它可以在任何地方。它无论如何都适用于程序集(全局适用于 .dll)。约定是将其放在.\Properties\AssemblyInfo.cs 文件中,其中. 是项目目录。它可能必须在任何 namespace 声明之外,或者这就是我遇到它或自己编写它时一直存在的地方。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-18
    相关资源
    最近更新 更多