2011-12-07 28 views
1

我想從遠程服務器更新我的exe文件。所以當按鈕點擊我的wpf應用程序時,它會下載遠程文件和一個遠程txt文件,並在運行exe的文件夾中替換當前文件。所以它會覆蓋當前的TXT和EXE文件,而我的exe文件正在運行。我怎樣才能做到這一點?如何從遠程主機更新您的exe文件 - c#4.0 - wpf應用程序

遠程主機URL像www.mydomain.com/MyAPP.exe

WPF應用程序,C#4.0

+0

您無法更新正在運行的程序。更新程序必須是一個單獨的可執行文件,它在要更新的應用程序未運行時運行。 – Joe

+0

那麼最好的方法是做什麼。我想當按鈕點擊它會調用該updater EXE,然後退出。我怎樣才能做到這一點 ? – MonsterMMORPG

回答

2

我們解決此問題的方法是創建,作爲一個已安裝並開始部署到客戶端機器,外殼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

解決方案取決於您的具體情況。但是沒有直接的解決方案,因爲在將程序集加載到內存中並被使用時不能更新程序集。我可以提出2個解決方案:使用shadow copying並使用某種助手可執行文件。我用過他們兩個。

影子複製。

顯而易見的方法是讓您的主要可執行文件被陰影複製,在應用程序運行時替換它,然後重新啓動應用程序。但是您的無法讓您的默認應用程序域被複制,只有輔助應用程序域可以。但是您仍然可以將所有代碼移動到另一個程序集(例如MainAppLib.dll)中,並重寫您的主應用程序可執行文件(MainApp.exe),使其僅包含「加載程序代碼」。該加載程序代碼必須創建另一個應用程序域,將其設置爲陰影複製,然後在輔助應用程序域中運行程序邏輯。請注意,不要將主應用程序域中的任何直接引用放入MainAppLib.dll中,因爲此程序集將加載到您的主應用程序域中,而不會複製陰影,並且程序集文件將被鎖定。在大多數情況下,您可以使用AppDomain.ExecuteAssembly()方法。

助手可執行

的想法是使用某種更新整理的。您的主應用程序保持不變,您只需在其中添加少量代碼,以便您的應用程序將下載更新,並將其放入臨時文件夾,然後您的主應用程序開始更新修整器(,單獨處理)並退出。更新裝訂器將等待您的應用程序關閉,然後將新文件從臨時文件夾複製到您的應用程序文件夾中,以替換所有文件。更新裝訂器不能替換它自己的可執行文件,但它可以在啓動更新裝訂器之前由主應用程序完成。複製文件後更新修整器運行您的應用程序。

p.s.我個人更喜歡前面的解決方案,因爲它涉及到使用應用程序域,反射,程序集e.t.c的某種巫術魔法。如果需要的話,它可以演變成使用插件(例如通過MEF framework)。但後者更容易理解,特別是如果您從未使用過應用程序域和手動程序集加載,這非常簡單。

1

您可以使用ClickOnce(基於上面的註釋,您將準備讓另一個程序集獲取該exe文件......因爲提到的另一個海報不能替換正在運行的程序集)。您可以將其配置爲在各種時間(例如,在啓動時)檢查新版本,並自動下載它們。它是一個非常強大的解決方案,您可以使用部署程序集進行很多工作。

相關問題