热卸载/重新加载应用程序使用的DLL
我有一个应用程序加载一个DLL来执行一个特定的部分处理
Example : "Application.dll" loading "Process.dll"
Process.dll是使用reflection在运行时dynamic加载的 ,而不是在应用程序中引用的。
处理完成后,需要在服务器上重新编译DLL,稍后再装回。
为了做到这一点,我需要释放它,否则我得到以下消息:“无法将文件”Process.dll“复制到”Process.dll“。进程无法访问文件”Process.dll“,因为它是被另一个进程使用“。
所以问题是:如何以编程方式释放/释放/卸载Process.dll
从我的应用程序再次加载之前。 当然,整个过程就是在不停止应用程序的情况下做到这一点。
编辑1:
build议的解决scheme如下所示:
AppDomain newDomain4Process = AppDomain.CreateDomain("newDomain4Process"); Assembly processLibrary = newDomain4Process.Load("Process.dll"); AppDomain.Unload(newDomain4Process);
我仍然存在的问题是,虽然我正在给适当的完整path,我得到一个FileNotFound Exception
。 这个post的答案也没有预期的效果。
编辑2:
这个post救了我的命,这里是代码:
class ProxyDomain : MarshalByRefObject { public Assembly GetAssembly(string AssemblyPath) { try { return Assembly.LoadFrom(AssemblyPath); } catch (Exception ex) { throw ex; } } } ProxyDomain pd = new ProxyDomain(); Assembly a = pd.GetAssembly(FullDLLPath);
编辑3:
虽然我没有获得AppDomain的访问权限,但是用以前的解决scheme卸载它。 当我使用AppDomain创build的经典方法时,我感觉到了Alexei的警告: AppDomain.Unload
“似乎”工作,但程序集仍然被加载(模块视图)。 所以我仍然有我的问题,因为我不能真正卸载DLL有效。
自从我看了这一段时间以来,我相当确信你需要创build一个新的AppDomain ,然后在那里加载DLL。
原因是你不能通过它自己卸载Assembly
,但是你可以卸载一个包含Assembly
的AppDomain
。
这是一个CodeProject文章,介绍如何做到这一点: 卸载正在运行的Dll
一旦程序集加载到AppDomain
,它就不能被卸载。 你必须处理AppDomain
。 如果您需要在应用程序中加载和卸载程序集,则需要生成一个新的AppDomain
并加载程序集,然后在完成程序集后,销毁AppDomain
。
虽然你似乎根据你的编辑解决这个问题,这里有一些评论:
注意你的Process.dll中的对象“泄漏”到主AppDomain中。 即像抛出Process.dll中定义的自定义exception,并在主AppDomain中捕获将强制Process.dll加载到主AppDomain。 在执行您感兴趣的操作后,检查主AppDomain中加载的程序集列表。
卸载AppDomain可能会失败,可能需要很长时间。