我有一个应用程序加载DLL来执行特定的处理部分
Example : "Application.dll" loading "Process.dll"
Run Code Online (Sandbox Code Playgroud)
Process.dll在运行时使用反射动态加载,而不是在应用程序中引用.
处理完成后,需要在服务器上重新编译DLL并稍后再次加载.
为了做到这一点,我需要释放它,否则我收到以下消息:"无法将文件"Process.dll"复制到"Process.dll".进程无法访问文件'Process.dll',因为它是被另一个进程使用."
所以问题是:如何Process.dll在重新加载之前以编程方式从我的应用程序中释放/释放/卸载.当然,重点是在不停止应用程序的情况下执行此操作.
编辑1:
建议的解决方案是这样的:
AppDomain newDomain4Process = AppDomain.CreateDomain("newDomain4Process");
Assembly processLibrary = newDomain4Process.Load("Process.dll");
AppDomain.Unload(newDomain4Process);
Run Code Online (Sandbox Code Playgroud)
我仍然遇到的问题是,虽然我给出了正确的完整路径,但我得到了一个FileNotFound Exception.这篇文章的答案也没有预期的效果.
编辑2:
这篇文章救了我的命,这里是代码:
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);
Run Code Online (Sandbox Code Playgroud)
编辑3:
我没有访问AppDomain并使用之前的解决方案卸载它.当我使用经典的AppDomain创建方法时,我感觉到阿列克谢的警告:AppDomain.Unload"似乎"工作,但程序集仍然被加载(模块视图).所以我仍然以某种方式遇到问题,因为我无法真正有效地卸载DLL.
我的.NET应用程序有不同版本的dll,大多数时候我想使用最新版本的dll.但是,有一种方法我在一个单独的线程上运行,我需要能够根据某些条件选择较旧版本的dll.
我已经知道不可能只加载一个程序集然后在默认的应用程序域中卸载它(我不能只保持两个版本都加载,因为那时我遇到了类型问题的重复定义)
可能我必须创建一个单独的AppDomain,在那里加载程序集然后卸载它.此应用程序域将在单独的线程上执行一个方法,并且可以使用该库的不同版本.
你认为这是一个好方法/你有更好的想法/你能指出一些能让我入手的资源吗?
非常感谢 ;)
我正在编写一个插件架构.我的插件dll位于运行插件管理器的子目录中.我将插件加载到单独的AppDomain中,如下所示:
string subDir;//initialized to the path of the module's directory.
AppDomainSetup setup = new AppDomainSetup();
setup.PrivateBinPath = subDir;
setup.ApplicationBase = subDir;
AppDomain newDomain= AppDomain.CreateDomain(subDir, null, setup);
byte[] file = File.ReadAllBytes(dllPath);//dll path is a dll inside subDir
newDomain.Load(file);
Run Code Online (Sandbox Code Playgroud)
然而.newDomain.Load返回当前域尝试加载的程序集.因为插件dll位于子目录中,所以当前域不能也不应该看到这些dll,并且当前域抛出FileLoadException"ex = {"无法加载文件或程序集......或其依赖项之一.
问题是,我们可以将程序集加载到单独的AppDomain中而不返回已加载的程序集吗?
我知道我可以在当前域中为AssemblyResolve事件添加一个处理程序并返回null,但我宁愿不去这条路线.
提前致谢.