我的DLL是由第三方应用程序加载的,我们无法对其进行自定义。我的程序集必须位于它们自己的文件夹中。我不能将它们放入GAC (我的应用程序需要使用XCOPY进行部署)。当根DLL尝试从另一个DLL (在同一文件夹中)加载资源或类型时,加载失败(FileNotFound)。是否可以通过编程方式(从根DLL)将DLL所在的文件夹添加到程序集搜索路径?不允许我更改应用程序的配置文件。
发布于 2009-09-03 13:04:33
听起来您可以使用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;
}
发布于 2009-09-03 12:30:50
您可以向应用程序的.config文件中添加probing path,但只有当探测路径包含在应用程序的基目录中时,它才会起作用。
发布于 2014-04-23 16:22:53
Framework 4的更新
由于Framework4也会为资源引发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;
}
}
https://stackoverflow.com/questions/1373100
复制相似问题