我有一個.exe程序集和一組引用的程序集,我希望能夠部署更新的代碼。我不需要實際更改運行代碼,但下次啓動可執行文件時,我希望它能夠獲取更新後的代碼。目前,當我嘗試複製正在運行的文件時,出現有關另一個進程正在使用的.exe文件的錯誤。如何更新正在運行的c#進程(AKA熱部署)的程序集?
總結;如何在.exe正在使用時更新代碼?
我有一個.exe程序集和一組引用的程序集,我希望能夠部署更新的代碼。我不需要實際更改運行代碼,但下次啓動可執行文件時,我希望它能夠獲取更新後的代碼。目前,當我嘗試複製正在運行的文件時,出現有關另一個進程正在使用的.exe文件的錯誤。如何更新正在運行的c#進程(AKA熱部署)的程序集?
總結;如何在.exe正在使用時更新代碼?
這很容易做到。您可以重命名該文件,Windows對該句柄有一個鎖定,而不是該文件的目錄條目。現在您可以複製更新而沒有問題。剩下要做的就是在應用程序重新啓動後襬脫重命名的文件。如有必要。
我不認爲這是可能的。例如,在零宕機時部署asp.net應用程序時,最佳做法是使用負載平衡器,以便取下一個實例,更新它,然後取下另一個實例進行更新。
裝配體在使用中時無法更新。這種情況的最佳選擇是製作一個小的可執行文件,它執行程序集的陰影副本,並從新位置啓動它們。
這樣,當用戶啓動程序時,您可以從部署站點複製(本地)複製,該複製始終可以被覆蓋。
ClickOnce給你一些選擇。 「應用程序啓動後更新」有update strategy。
對於更復雜的場景,有System.Deployment namespace。例如,您可以定期輪詢應用程序中的更新。
只是一個想法:嘗試MEF和[導入[ 「http://someRemoteResource」]]
有關以下內容:
最好的想法應該是已經提出的其他答案之一...就像使用MEF和/或ClickOnce進行重構一樣。但是,這些解決方案無法幫助您進行「部署」。他們要求您對exe文件進行更改,或者創建引導程序可執行文件,這隻會幫助您進行下一次部署。
對於此部署你可以嘗試這樣做(我從來沒有這樣做過,但理論上它可以工作):
RunOnce鍵包含命令行命令,它們在重新啓動時運行一次,然後從註冊表中刪除,以便它們不會再次運行。這就是InstallShield如何允許您在其他應用程序正在使用時覆蓋某些dll的方式。
本課程將重新命名當前運行的可執行文件,如果它完成無一例外,你可以簡單地寫入新的可執行文件,然後重新啓動,如:
Ourself.Rename();
// Download or copy new version
File.Copy(newVersion, Ourself.FileName());
// Launch new version
System.Diagnostics.Process.Start(Ourself.FileName());
// Close current version
Close(); // Exit();
簡單就夠了嗎?
class Ourself
{
public static string FileName() {
Assembly _objParentAssembly;
if (Assembly.GetEntryAssembly() == null)
_objParentAssembly = Assembly.GetCallingAssembly();
else
_objParentAssembly = Assembly.GetEntryAssembly();
if (_objParentAssembly.CodeBase.StartsWith("http://"))
throw new IOException("Deployed from URL");
if (File.Exists(_objParentAssembly.Location))
return _objParentAssembly.Location;
if (File.Exists(System.AppDomain.CurrentDomain.BaseDirectory + System.AppDomain.CurrentDomain.FriendlyName))
return System.AppDomain.CurrentDomain.BaseDirectory + System.AppDomain.CurrentDomain.FriendlyName;
if (File.Exists(Assembly.GetExecutingAssembly().Location))
return Assembly.GetExecutingAssembly().Location;
throw new IOException("Assembly not found");
}
public static bool Rename()
{
string currentName = FileName();
string newName = FileName() + ".ori";
if (File.Exists(newName))
{
File.Delete(newName);
}
File.Move(currentName, newName);
return true;
}
}
似乎有一個Codeplex項目針對.NET的熱部署。我還沒有嘗試,但:http://hotdeploy.codeplex.com/ – 2010-02-25 16:48:49