我的目录结构如下所示:
-- Host Program Base
|- HostProgram.exe
|- SharedLIB.dll
|-- LoadedLibs
|- HostedLib.dll
HostProgram.exe
正在尝试加载HostedLib.dll
,这取决于SharedLib.dll
。
因此,SharedLib.dll
ApplicationBase
我正在创建的加载它的AppDomain
是/Host Program Base/HostedLibs/
,但它需要能够找到SharedLib.dll
。
我试图在AppDomain
的PrivateBinPath
中添加..
,但根据 MSDN,
专用程序集部署在与应用程序相同的目录结构中。如果为 PrivateBinPath 指定的目录不在 ApplicationBase 下,则忽略这些目录。
由于PrivateBinPath
不在ApplicationBase
内,而是一个目录,因此它不在ApplicationBase
内,因此被忽略。因此,我在尝试将 DLL 加载到新AppDomain
时出现AssemblyResolveException
。
我还尝试将ApplicationBase
设置为Host Program Base
文件夹并添加HostedLibs
作为PrivateBinPath
,但这会导致域根本无法解析HostedLib.dll
。
那么 ->如何使用AppDomainSetup
解析ApplicationBase
之外的库?
如果不重新组织应用程序结构,您可以使用AppDomain.AssemblyResolve event
。
基本上是这样的。
- 订阅 AppDomain 上的 AssemblyResolve 事件。
- 当事件触发时,您可以专门查找您的 SharedLib.dll或者只是尝试在根文件夹中创建所需程序集的完整路径,给定
ResolveEventArgs.Name
中指定的程序集名称并使用Assembly.LoadFrom(path)
。 - 如果程序集成功从路径加载,则在 AssemblyResolve 处理程序中返回它,否则返回
null
。
基于Jim的答案实现的解决方案:
internal static class Program
{
static Program()
{
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainOnAssemblyResolve;
}
private static void Main()
{
//Do your stuff
}
private static Assembly CurrentDomainOnAssemblyResolve(object sender, ResolveEventArgs args)
{
try
{
AssemblyName name = new AssemblyName(args.Name);
string expectedFileName = name.Name + ".dll";
string rootDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
return LoadAssembly(rootDir, expectedFileName, "", "Dlls", "../Dlls");
}
catch
{
return null;
}
}
private static Assembly LoadAssembly(string rootDir, string fileName, params string[] directories)
{
foreach (string directory in directories)
{
string path = Path.Combine(rootDir, directory, fileName);
if (File.Exists(path))
return Assembly.LoadFrom(path);
}
return null;
}
}