一. 摘要
最近一兩年在做跨平台的解決方案,使應用程式能支援Android, iOS, Windows, MacOs. Linux等作業系統,在Android, iOS上可以使用Google Play Store 和 Apple App Store 隻帶的自動更新特性,但在Windows, MacOs. Linux,就需要自己寫解決方案。
今天新加坡國慶節,由于肺炎疫情,宅在家沒事,就完成了從CodePlex到Github的遷移,該元件已經成功托管到Github,是以大家可以到上面下載下傳其源代碼,也可以送出Issue,具體位址:https://github.com/knightswarrior/AppAutoUpdater
2010年我在CodePlex上開源了這個架構,在十年時間内下載下傳量接近百萬,感謝各位社群朋友的支援,我也盡力在努力更新,同時也盡量在工作之餘回答各位在使用中的問題,但是可能有一些沒有回複到,希望各位海涵。
衆所周知,對于一般的軟體開發,在開始的時候都會有一個技術選型的階段,最大的選型就是首先要确定是選擇Client/Server模式還是Browser/Server模式。綜合而論:兩者各有優劣,在很多方面都不能被對方互相取代,如在适用Internet、維護工作量等方面,B/S比C/S要強很多;但在運作速度、資料安全、人機互動等方面,B/S就遠不如C/S那麼強大。是以綜上所述,凡是C/S的強項,便是B/S的弱項,反之亦然。由于今天讨論的是自動更新元件,是以接下來我們就往這方面細講,既然C/S模式在運作速度、資料安全、人機互動有這麼多的優點,尤其是用戶端技術日益發展的今天,如何解決用戶端的部署與自動更新問題便是一個非常重要的問題。
二. 本文提綱
· 1.摘要
· 2.本文提綱
· 3.為什麼不使用ClickOnce
· 4.簡要介紹
· 5.項目中如何使用
· 6.具體效果
· 7.維護與下載下傳
· 8.總結
三. 為什麼不使用ClickOnce
在前面的摘要中我們簡單介紹了自動更新功能的重要性,在這一小節裡我們來談一下為什麼不使用微軟給我們提供的自動更新元件ClickOnce,大家都知道ClickOnce給我們提供了很多功能:簡單說來,ClickOnce 應用程式就是任何使用 ClickOnce 技術釋出的 Windows 窗體或控制台應用程式。可以采用三種不同的方法釋出 ClickOnce 應用程式:從網頁釋出、從網絡檔案共享釋出或是從媒體(如 CD-ROM)釋出。ClickOnce 應用程式既可以安裝在最終使用者的計算機上并在本地運作(即使當計算機脫機時也可以運作),也可以僅以聯機模式運作,而不在最終使用者的計算機上永久安裝任何内容。ClickOnce 應用程式可以自行更新;這些應用程式可以在較新版本變為可用時檢查較新版本,并自動替換所有更新的檔案。開發人員可以指定更新行為;網絡管理者也可以控制更新政策,如将更新标記為強制性的。最終使用者或管理者還可以對更新進行復原,使應用程式恢複到早期的版本。
從上面大家可以看出ClickOnce 無疑是微軟對Client/Server模式部署的最佳解決方案,但正是因為它的功能特别強大而且又要使用相當簡單,是以在産品的封裝上就特别嚴實,基本上就暴露了一些簡單的操作接口,這樣就無形把一些定制化的操作拒之于門外,比如:
1,使用者不能自己指定安裝路徑。
2,對自動更新流程不能做定制化的操作。
3,對自動更新的UI不能定制化的設計。
正因為這幾個原因,是以很多企業都會做一些定制化的元件來實作自動更新的功能,基于此,我們這裡也實作了一個非常簡單的自動更新元件.
四. 簡要介紹
其實自動更新的原理很簡單,分析起來無非就是簡單的幾步操作,當然實作方式也是大同小異,這裡我們就選一種較簡單的方式:
1.啟動主程式,主程式裡面調用更新程式,更新程式連接配接到IIS或者FTP。
2.更新程式擷取伺服器端XML配置檔案中新版本程式的更新日期或版本号或檔案大小。
3.更新程式擷取原有用戶端應用程式的最近一次更新日期或版本号或檔案大小,然後兩者進行比較;如果新版本日期>原有程式的最新日期,則提示使用者是否更新;或如果新版本版本号>原有程式的版本号,則提示使用者是否更新;再或如果新版本檔案大小>原有程式的檔案大小,則提示使用者是否更新。本文主要采用一般的做法,就是通過版本号來進行對比。
4.如果使用者選擇更新,則擷取下載下傳檔案清單;
5.在本地建立與遠端IIS或者FTP相應的臨時目錄,然後下載下傳到這個臨時目錄檔案下;
6.删除舊的主程式,拷貝臨時檔案夾中的檔案到相應的位置;
8.結束更新流程并重新啟動主程式。
根據前面的流程,我們可以簡單設計如下的項目:
圖1
具體類介紹:
IAutoUpdater.cs 提供外部調用的接口
AutoUpdater.cs 該元件的主操作類
Autoupdater.config 本地配置檔案
DownloadConfirm.cs 提示是否有更新頁面
DownloadProgress.cs 下載下傳進度頁面
CommonUnitity.cs 一些常用功能
Config.cs 當更新完畢之後需要更新Config,是以這裡需要一個提供序列化的Config類
ConstFile.cs 一些常量檔案
DownloadFileInfo.cs 需要下載下傳的檔案實體類
LocalFile.cs 本地檔案實體類
RemoteFile.cs 遠端檔案實體類
UpdateFileList.cs 本地的實體類集合
代碼非常簡單,具體可以下載下傳進行檢視,是以這裡就不做過多闡述。
五. 項目中如何使用
第一步:Host更新的版本到伺服器
如果需要讓用戶端擷取最新的版本,首先我們需要開發人員編譯源代碼并生成檔案,然後拷貝到FTP,伺服器或者雲端目錄下,運作一個自動生成XML檔案的程式,把所有的檔案都自動生成到一個XML檔案,詳細見下圖:
圖2
第二步:配置本地的Config
經過第一步的流程,這一步要做的就是配置本地的Config用于監測并下載下傳遠端IIS或者FTP下需要更新的檔案,具體如下圖所示:
圖3
第三步:修改主程式
首先把AutoUpdater這個DLL引入我們的主項目,然後在主項目中添加如下代碼,當然你可以根據自己的需要進行書寫,這個DLL提供了兩個外部接口,一個接口用于判斷是否有更新及下載下傳,另一個接口則是用于更新出錯時進行復原操作,具體代碼如下:
#region check and download new version program
bool bHasError = false;
IAutoUpdater autoUpdater = new AutoUpdater();
try
{
autoUpdater.Update();
}
catch (WebException exp)
{
MessageBox.Show("Can not find the specified resource");
bHasError = true;
}
catch (XmlException exp)
{
bHasError = true;
MessageBox.Show("Download the upgrade file error");
}
catch (NotSupportedException exp)
{
bHasError = true;
MessageBox.Show("Upgrade address configuration error");
}
catch (ArgumentException exp)
{
bHasError = true;
MessageBox.Show("Download the upgrade file error");
}
catch (Exception exp)
{
bHasError = true;
MessageBox.Show("An error occurred during the upgrade process");
}
finally
{
if (bHasError == true)
{
try
{
autoUpdater.RollBack();
}
catch (Exception)
{
//Log the message to your file or database
}
}
}
#endregion
使用就是這麼簡單,更詳細的操作,大家可以下載下傳源碼,也正因為它的簡單,是以大家可以對其修改以滿足具體項目的需求。
六. 具體效果
當我們運作主程式(WinForm或者WPF),如果伺服器上有最新的版本,就會彈出如下頁面進行提示并讓使用者選擇是否更新。
圖4
當使用者不需要更新時,可以選擇Skip按鈕跳過并繼續主程式流程,反之則進入如下頁面。
圖5