如何在运行时在.NET中将文件夹添加到程序集搜索路径中?

我的DLL由第三方应用程序加载,我们无法自定义。 我的程序集必须位于它们自己的文件夹中。 我无法将它们放入GAC(我的应用程序需要使用XCOPY进行部署)。 当根DLL尝试从另一个DLL(在同一文件夹中)加载资源或类型时,加载失败(FileNotFound)。 是否可以通过编程方式(从根DLL)将我的DLL所在的文件夹添加到程序集搜索路径中? 我不允许更改应用程序的配置文件。


听起来你可以使用AppDomain.AssemblyResolve事件并手动加载DLL目录中的依赖关系。

编辑(来自评论):

AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += new ResolveEventHandler(LoadFromSameFolder);

static Assembly LoadFromSameFolder(object sender, ResolveEventArgs args)
{
    string folderPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    string assemblyPath = Path.Combine(folderPath, new AssemblyName(args.Name).Name + ".dll");
    if (!File.Exists(assemblyPath)) return null;
    Assembly assembly = Assembly.LoadFrom(assemblyPath);
    return assembly;
}

您可以将探测路径添加到应用程序的.config文件,但只有探测路径包含在您的应用程序的基本目录中时才能使用。


更新框架4

由于Framework 4也为资源引发了AssemblyResolve事件,因此该处理程序的效果更好。 它基于这样一个概念,即本地化位于app子目录(一个用于文化名称的本地化,例如C: MyApp it意大利语)。里面有资源文件。 如果本地化是国家区域,即it-IT或pt-BR,处理程序也可以工作。 在这种情况下,处理程序“可能会多次调用:对于后备链中的每种文化都会调用一次”[来自MSDN]。 这意味着如果我们为“it-IT”资源文件返回null,框架会引发事件询问“it”。

事件挂钩

        AppDomain currentDomain = AppDomain.CurrentDomain;
        currentDomain.AssemblyResolve += new ResolveEventHandler(currentDomain_AssemblyResolve);

事件处理器

    Assembly currentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        //This handler is called only when the common language runtime tries to bind to the assembly and fails.

        Assembly executingAssembly = Assembly.GetExecutingAssembly();

        string applicationDirectory = Path.GetDirectoryName(executingAssembly.Location);

        string[] fields = args.Name.Split(',');
        string assemblyName = fields[0];
        string assemblyCulture;
        if (fields.Length < 2)
            assemblyCulture = null;
        else
            assemblyCulture = fields[2].Substring(fields[2].IndexOf('=') + 1);


        string assemblyFileName = assemblyName + ".dll";
        string assemblyPath;

        if (assemblyName.EndsWith(".resources"))
        {
            // Specific resources are located in app subdirectories
            string resourceDirectory = Path.Combine(applicationDirectory, assemblyCulture);

            assemblyPath = Path.Combine(resourceDirectory, assemblyFileName);
        }
        else
        {
            assemblyPath = Path.Combine(applicationDirectory, assemblyFileName);
        }



        if (File.Exists(assemblyPath))
        {
            //Load the assembly from the specified path.                    
            Assembly loadingAssembly = Assembly.LoadFrom(assemblyPath);

            //Return the loaded assembly.
            return loadingAssembly;
        }
        else
        {
            return null;
        }

    }
链接地址: http://www.djcxy.com/p/7733.html

上一篇: How to add folder to assembly search path at runtime in .NET?

下一篇: Based Authentication in SQL Server