我想從遠程服務器更新我的exe文件。所以當按鈕點擊我的wpf應用程序時,它會下載遠程文件和一個遠程txt文件,並在運行exe的文件夾中替換當前文件。所以它會覆蓋當前的TXT和EXE文件,而我的exe文件正在運行。我怎樣才能做到這一點?如何從遠程主機更新您的exe文件 - c#4.0 - wpf應用程序
遠程主機URL像www.mydomain.com/MyAPP.exe
WPF應用程序,C#4.0
我想從遠程服務器更新我的exe文件。所以當按鈕點擊我的wpf應用程序時,它會下載遠程文件和一個遠程txt文件,並在運行exe的文件夾中替換當前文件。所以它會覆蓋當前的TXT和EXE文件,而我的exe文件正在運行。我怎樣才能做到這一點?如何從遠程主機更新您的exe文件 - c#4.0 - wpf應用程序
遠程主機URL像www.mydomain.com/MyAPP.exe
WPF應用程序,C#4.0
我們解決此問題的方法是創建,作爲一個已安裝並開始部署到客戶端機器,外殼EXE 。
「真正的」可執行程序存儲在這個初始應用程序的子目錄中。當shell應用程序啓動後,它下載並安裝了真實應用程序的任何更新後,它會在單獨的AppDomain中啓動真實應用程序的可執行文件。
這裏是「真正的」應用的啓動從外殼應用中的核心:
System.AppDomainSetup oSetup = new System.AppDomainSetup();
string sApplicationFile = null;
// Use this to ensure that if the application is running when the user performs the update, that we don't run into file locking issues.
oSetup.ShadowCopyFiles = "true";
oSetup.ApplicationName = sAppName;
// Generate the name of the DLL we are going to launch
sApplicationFile = System.IO.Path.Combine(sApplicationDirectory, sAppName + ".exe");
oSetup.ApplicationBase = sApplicationDirectory;
oSetup.ConfigurationFile = sApplicationFile + ".config";
oSetup.LoaderOptimization = LoaderOptimization.MultiDomain;
// Launch the application
System.AppDomain oAppDomain = AppDomain.CreateDomain(sAppName, AppDomain.CurrentDomain.Evidence, oSetup);
oAppDomain.SetData("App", sAppName);
oAppDomain.SetData("User", sUserName);
oAppDomain.SetData("Pwd", sUserPassword);
oAppDomain.ExecuteAssembly(sApplicationFile);
// When the launched application closes, close this application as well
Application.Exit();
注意,在我們的版本,外殼程序,以便收集來自用戶的用戶名和密碼訪問更新網站正確。然後通過AppDomain上的SetData
方法將此數據傳遞給「真實」應用程序。
解決方案取決於您的具體情況。但是沒有直接的解決方案,因爲在將程序集加載到內存中並被使用時不能更新程序集。我可以提出2個解決方案:使用shadow copying並使用某種助手可執行文件。我用過他們兩個。
影子複製。
顯而易見的方法是讓您的主要可執行文件被陰影複製,在應用程序運行時替換它,然後重新啓動應用程序。但是您的無法讓您的默認應用程序域被複制,只有輔助應用程序域可以。但是您仍然可以將所有代碼移動到另一個程序集(例如MainAppLib.dll)中,並重寫您的主應用程序可執行文件(MainApp.exe),使其僅包含「加載程序代碼」。該加載程序代碼必須創建另一個應用程序域,將其設置爲陰影複製,然後在輔助應用程序域中運行程序邏輯。請注意,不要將主應用程序域中的任何直接引用放入MainAppLib.dll中,因爲此程序集將加載到您的主應用程序域中,而不會複製陰影,並且程序集文件將被鎖定。在大多數情況下,您可以使用AppDomain.ExecuteAssembly()方法。
助手可執行
的想法是使用某種更新整理的。您的主應用程序保持不變,您只需在其中添加少量代碼,以便您的應用程序將下載更新,並將其放入臨時文件夾,然後您的主應用程序開始更新修整器(,單獨處理)並退出。更新裝訂器將等待您的應用程序關閉,然後將新文件從臨時文件夾複製到您的應用程序文件夾中,以替換所有文件。更新裝訂器不能替換它自己的可執行文件,但它可以在啓動更新裝訂器之前由主應用程序完成。複製文件後更新修整器運行您的應用程序。
p.s.我個人更喜歡前面的解決方案,因爲它涉及到使用應用程序域,反射,程序集e.t.c的某種巫術魔法。如果需要的話,它可以演變成使用插件(例如通過MEF framework)。但後者更容易理解,特別是如果您從未使用過應用程序域和手動程序集加載,這非常簡單。
您可以使用ClickOnce(基於上面的註釋,您將準備讓另一個程序集獲取該exe文件......因爲提到的另一個海報不能替換正在運行的程序集)。您可以將其配置爲在各種時間(例如,在啓動時)檢查新版本,並自動下載它們。它是一個非常強大的解決方案,您可以使用部署程序集進行很多工作。
您無法更新正在運行的程序。更新程序必須是一個單獨的可執行文件,它在要更新的應用程序未運行時運行。 – Joe
那麼最好的方法是做什麼。我想當按鈕點擊它會調用該updater EXE,然後退出。我怎樣才能做到這一點 ? – MonsterMMORPG