如何在运行时在.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?