當某個程序集文件被載入AppDomain,該文件在AppDomain.Unload之前是不能被替換和刪除的。
使用AppDomainSetup的影像復制功能可以實現在不卸載程序的情況下替換或者刪除程序集文件。
AppDomain domain = AppDomain.CreateDomain("a");
domain.ExecuteAssembly(@"loads\test.exe");
File.Delete(@"loads\test.exe");
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");
// 打開影像復制。
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");
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, 這回沒問題了。