提供外部程序集本机dll依赖项的路径

时间:2011-05-31 10:00:25

标签: c# pinvoke

我有C#应用程序,它加载了一组托管程序集。如果它们是可用的,则其中一个程序集加载两个本机dll(每个dll位于不同的位置)。我试图找到为这些本地dll提供搜索路径的方法。

还有其他选择吗?我真的不想用我的软件提供这些dll - 将它们复制到程序目录当然可以解决问题。

我尝试过使用 SetDllDirectory 系统函数,但是只能使用它来提供一个路径。每次调用此函数都会重置路径。

设置 PATH 环境变量也无法解决问题:/

3 个答案:

答案 0 :(得分:0)

这可能有所帮助:

    private void Form1_Load(object sender, EventArgs e)
    {
        //The AssemblyResolve event is called when the common language runtime tries to bind to the assembly and fails.
        AppDomain currentDomain = AppDomain.CurrentDomain;
        currentDomain.AssemblyResolve += new ResolveEventHandler(currentDomain_AssemblyResolve);
    }

    //This handler is called only when the common language runtime tries to bind to the assembly and fails.
    Assembly currentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        string dllPath = Path.Combine(YourPath, new AssemblyName(args.Name).Name) + ".dll";
        return (File.Exists(dllPath))
            ? Assembly.Load(dllPath)
            : null;
    }

答案 1 :(得分:0)

我知道这是一篇老文章,但有一个答案:使用LoadLibary函数可以强制加载本机DLL:

public static class Loader
{
    [DllImport("kernel32.dll")]
    public static extern IntPtr LoadLibrary(string fileName);
}

您必须先调用此函数,然后再执行其他DLL-我通常在主程序的静态构造函数中调用它。我必须为DllImport()进行此操作,并且静态构造函数始终在加载本机DLL之前执行-它们仅在第一次调用导入的函数时才实际加载。

示例:

class Program
{
    static Program()
    {
       Loader.LoadLibrary("path\to\native1.dll");
       Loader.LoadLibrary("otherpath\to\native2.dll");
    }
}

一旦库被加载,它就应该满足您正在加载的其他托管程序集的DllImports()。如果没有,则可能会使用其他方法加载它们,您可能别无选择,只能在本地复制它们。

注意:这仅是Windows解决方案。为了使它更具跨平台性,您必须自己检测操作系统并使用正确的导入。例如:

    [DllImport("libdl")] 
    public static extern IntPtr DLOpen(string fileName, int flags);

    [DllImport("libdl.so.2")]
    public static extern IntPtr DLOpen2(string fileName, int flags);
    // (could be "libdl.so.2" also: https://github.com/mellinoe/nativelibraryloader/issues/2#issuecomment-414476716)

    // ... etc ...

答案 2 :(得分:-1)

将您的dll注册到GAC。更多here