解析大型.NET ERP系統 自動更新

C/S架構的應用程序須要支持自動更新功能,當新版本程序發佈後,正在運行的客戶端能檢測到新版本的程序,通知用戶是否下載更新。工做以來參與過幾個自動更新模塊的設計與維護,撰文總結自動更新模塊設計與實現。html

自動更新組件主要內容

1  版本比較。舊版本如何檢測到新版本,版本信息是程序集自描述的,仍是用單獨的文件保存。.NET程序集是自描述的,程序集包含如下幾種版本信息,每一個Assebmly包含三個Version
AssemblyFileVersion : 存儲在Win32資源中, CLR不關心這個版本號。
AssemblyInformationnalVersion :存儲在Win32資源中, CLR不關心這個版本號。
AssemblyVersion: 存儲在AssemblyDef manifest metadata table中,CLR會使用這個版本號。windows

標準版本號物理形式表示爲用句點隔開的四段數字,以下面的代碼示例所示。
<major version>.<minor version>.<build number>.<revision>
實際使用中,咱們通常只用到前面三段。即
<major version>.<minor version>.<build number> 服務器

版本比較舉例: 網絡

舊版本 2.4.1.2 架構

新版本 2.4.1.3 或 2.4.2.2 或2.5.1.2。 異步

2 程序下載。採用何種方式,從哪裏下載最新版本的程序。 優化

1) Http 協議。從IIS或Tomcat 等Web服務器中下載新版本的程序文件。 網站

2) Ftp協議。從Ftp服務器下載新版本的程序文件。 ui

3) 局域網共享。從內部局域網下載新版本的程序文件。 spa

下載過程當中應該支持斷點續傳,支持以壓縮文件的方式傳輸,下載完成後自動解壓縮,執行更新。還能夠參考Windows的BITS更新服務,BITS (後臺智能傳送服務) 是一個 Windows 組件,它能夠在前臺或後臺異步傳輸文件,爲保證其餘網絡應用程序得到響應而調整傳輸速度,並在從新啓動計算機或從新創建網絡鏈接以後自動恢復文件傳輸。

爲了達到傳輸過程當中速度最優化,能夠考慮調用第三方下載API,實現穿越局域網時,下載速度最快。

4) ClickOnce方式。將程序部署在IIS網站中,配置ClickOnce,參考文章 ClickOnce部署

 

3 執行更新。若是更新程序是壓縮格式的zip/rar格式文件,可解壓縮後複製到應用程序目錄便可。若是更新程序是安裝格式的Installer文件,則須要先退出當前程序,啓動安裝程序包。

當前程序正在執行時,將更新程序覆蓋過來,會遇到文件被進程佔用的狀況,有如下三種解決方案:

1) 根據更新程序生成一個批處理命令,主要內容是將更新程序中的文件複製到當前程序所在文件夾。命令主要包含如下三個部分,退出當前程序,執行文件複製,啓動應用程序。

2) 應用程序啓動一個獨立的更新程序Update.EXE,由更新程序完成文件的複製和程序的啓動。

3) 調用Volume Shadow Copy Service,這個服務支持當文件正在被進程使用,仍能夠複製。

詳細參考如下網站信息 Volume Shadow Copy Service

 

文件的存儲方式

1) 文件包含版本信息,舉例EnterpriseSolution-5.3.0.0-20150401.zip,表示是5.3版本的,構建日期是2015年4月1日。在檢測更新文件時,須要遍歷同版本或是高版本的文件,取最新的那個文件。

2) 文件不包含版本信息,須要用獨立的描述文件表達版本信息。好比

<?xml version="1.0" encoding="utf-8" ?>
<Content>
  <Project id="Enterprise.Sales.dll" Edition="1.2"> </Project>
  <Project id="Enterprise.Purchasing.dll" Edition="1.2"> </Project>
  <Project id="Enterprise.Inventory.dll" Edition="1.3"> </Project>
  <Project id="Enterprise.GeneralLedger.dll" Edition="1.5"> </Project>
</Content>

經過這個描述文件,找到最新版本的文件,分批下載回來。對於服務器中存在多個版本的文件狀況,可用文件夾(1.2,1.5)的方式將各版本的程序文件放在各自的目錄中,經過上面的版本描述文件分別在各自的版本目錄中尋找文件。

 

版本檢測

檢測版本,發現新版本後啓動更新程序Update.EXE,退出當前程序。

string clientVersion = FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly().Location).ProductVersion;
string serverVersion = FileVersionInfo.GetVersionInfo("Main.exe", server)).ProductVersion;

if (new Version(serverVersion).CompareTo(new Version(clientVersion)) > 0)
{
        var process = new Process
        {
                 StartInfo = new ProcessStartInfo
                 {
                      FileName = "Update.exe",
                      Arguments = "LOCAL"
                  }
        };
        process.Start();
        Environment.Exit(0);
}
 
 

外殼程序

啓動外殼程序,在局域網(工做組)中經常使用來解決權限問題。

private static void Shell(string arguments)
{
        Process process = new Process();
        ProcessStartInfo processStartInfo = new ProcessStartInfo("cmd.exe", arguments);
        processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
        process.StartInfo = processStartInfo;
        process.Start();
}
 

經常使用在net use命令,舉例以下:

net use ipipc$ " " /user:" " 創建IPC空連接

net use ipipc$ "密碼" /user:"用戶名" 創建IPC非空連接

net use h: ipc$ "密碼" /user:"用戶名" 直接登錄後映射對方C:到本地爲H:

net use h: ipc$ 登錄後映射對方C:到本地爲H:

 

網絡鏈接檢查

當準備檢測更新時,我須要檢測網絡是否通暢,須要用下面的方法:

1) 局域網模式下,用SystemInformation.Network可達到目的。

2) 要從外網下載程序,須要檢查外網是否連通,能夠採用PING一個IP地址的方式,要求這個IP地址或是域名很是穩定。

能夠調用C#的Ping類型完成目的,參考代碼:

Ping ping = new Ping();
PingOptions poptions = new PingOptions();
poptions.DontFragment = true;

也能夠調用COM接口InternetGetConnectedState,用於檢測網絡鏈接狀態。

[DllImport("wininet")]
private extern static bool InternetGetConnectedState(out int connectionDescription, int reservedValue);

參考說明 InternetGetConnectedState function

stackoverflow中有一篇講解判斷網絡鏈接的問答,地址是http://stackoverflow.com/questions/13457407/why-is-getisnetworkavailable-always-returning-true

要檢測廣域網是否鏈接,須要使用InternetGetConnectedState()或WinINet API。

相關文章
相關標籤/搜索