且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

C#.Net 如何动态加载与卸载程序集(.dll或者.exe)6-----在不卸载程序域的前提下替换程序集文件。

更新时间:2022-06-15 09:03:20

原文:C#.Net 如何动态加载与卸载程序集(.dll或者.exe)6-----在不卸载程序域的前提下替换程序集文件。

当某个程序集文件被载入AppDomain,该文件在AppDomain.Unload之前是不能被替换和删除的。
使用AppDomainSetup的影像复制功能可以实现在不卸载程序的情况下替换或者删除程序集文件。

AppDomain domain = AppDomain.CreateDomain("a");
domain.ExecuteAssembly(@"loads\test.exe");
File.Delete(@"loads\test.exe");


上述代码没有在删除文件前调用 AppDomain.Unload(domain); ,所以会出现"拒绝访问"的异常。
接下来我们打开影像复制功能,你会发现目标程序集文件被正确删除。

AppDomain domain = AppDomain.CreateDomain("a");

// 打开影像复制。
domain.SetShadowCopyFiles();
// 设置要进行影像设置的程序集路经。
domain.SetShadowCopyPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "loads"));

domain.ExecuteAssembly(@"loads\test.exe");
File.Delete(@"loads\test.exe");


我们在"loads\test.exe"中使用"Assembly.GetExecutingAssembly().Location"查看,你会发现程序集文件被复制到"c:\documents and settings\user1\local settings\application data\assembly\dl2\6e9nkvqy.yol\dhp83obd.j9j\9730b8d1\00fb5179_6d04c601\test.exe"这样一个目录中,这也是程序集被正确删除的根本原因(^_^)。正因为目标程序集的位置发生变化,因此我们要做更进一步的设置,否则目标程序集在加载动态引用或者读取配置文件时出错。

AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "loads");
setup.ConfigurationFile = Path.Combine(setup.ApplicationBase, "test.exe.config");
setup.ShadowCopyFiles = "true";
setup.ShadowCopyDirectories = setup.ApplicationBase;

AppDomain domain = AppDomain.CreateDomain("a", null, setup);
domain.ExecuteAssembly(@"loads\test.exe");

File.Delete(@"loads\test.exe");


ok, 这回没问题了。