所以最近我一直致力于一个项目,在这个项目中,应用程序(或可执行文件,无论你想称之为什么)都是 needs to be able to load and unload assemblies not found within the executable's folder . (甚至可能是另一个驱动器)
为了举个例子,我希望能够将我的应用程序放在 D:\AAA\theAppFolder ,并将DLL文件的程序集放在 C:\BBB\Assemblies
仔细观察,我发现 AppDomain 允许卸载自己和任何附加组件的能力,所以我想我会试一试,但是经过几个小时的尝试后似乎有问题:AppDomains无法看到外面的任何地方应用基础 .
根据AppDomain的纪录片(以及我自己的经验)你不能在ApplicationBase之外设置PrivateBinPath,如果我在应用程序所在的驱动器之外设置ApplicationBase(通过AppDomainSetup),我得到 System.IO.FileNotFoundException 抱怨它无法找到应用程序本身 .
因此我甚至无法达到可以使用AssemblyResolve ResolveEventHandler尝试使用MarhsalByRefObject继承类来获取程序集的阶段...
这里有一些与我目前正在尝试的代码相关的代码片段
internal class RemoteDomain : MarshalByRefObject
{
public override object InitializeLifetimeService() //there's apparently an error for marshalbyref objects where they get removed after a while without this
{
return null;
}
public Assembly GetAssembly(byte[] assembly)
{
try
{
return Assembly.Load(assembly);
}
catch (Exception e)
{
Console.WriteLine(e);
}
return null;
}
public Assembly GetAssembly(string filepath)
{
try
{
return Assembly.LoadFrom(filepath);
}
catch (Exception e)
{
Console.WriteLine(e);
}
return null;
}
}
public static Assembly LoadAssembly(string modName, BinBuffer bb)
{
string assembly = pathDirTemp+"/"+modName+".dll";
File.WriteAllBytes(assembly, bb.ReadBytes(bb.BytesLeft()));
RemoteDomain loader = (RemoteDomain)modsDomain.CreateInstanceAndUnwrap(typeof(RemoteDomain).Assembly.FullName, typeof(RemoteDomain).FullName);
return loader.GetAssembly(assembly);
}
尽可能具体: Is there any way to get an unloadable AppDomain to load an assembly that is not within the application's base folder?
2 回答
每个
AppDomain
都有自己的基本目录,并不受主应用程序基础dir的约束(除非它是应用程序的主AppDomain) . 因此,您可以使用AppDomains实现您想要的功能 .您的方法不起作用的原因是您在AppDomains之间传递Assembly对象 . 当您调用任何
GetAssembly
方法时,程序集将加载到子AppDomain中,但是当该方法返回时,主AppDomain也将尝试加载程序集 . 当然,程序集将无法解析,因为它不在主AppDomains的基本目录,私有路径或GAC中 .所以通常你不应该在
AppDomains
之间传递Type
或Assembly
个对象 .可以在this answer中找到加载程序集而不将其泄漏到主AppDomain的简单方法 .
当然,为了使您的应用程序能够在子AppDomain中加载程序集,您必须创建
MarshalByRefObject
派生类,它们将成为AppDomains之间的访问点 .也许您需要使用全局变量,因此如果您使用全局变量来修复问题,您可以声明readonly全局变量,例如:
将其转换为
无论如何,您不能将全局动态值变量用于CLR程序集 .