【WPF】軟件更新程序的設計思路


目標:客戶端程序在啟動時,自動聯網檢查服務端是否有新的版本,有則提示用戶更新客戶端。

思路:

1、打開Visual Studio,在主體程序的解決方案下再新建一個叫自動更新程序的項目。主體程序的目錄是D:\workspace\MyProject\Client\自動更新程序的目錄是D:\workspace\MyProject\UpdateTool\

2、最后打包出來時將兩個項目合並在一個Debug文件中。只需把自更程序exe和它依賴的dll文件一並拷到主體程序打包出來的Debug文件夾下即可。此時Debug文件夾下會有兩個exe(自更程序UpdateTool.exe和主體程序Client.exe),如果從自更程序exe啟動,就先檢查版本再啟動主體程序;如果從主體程序exe啟動,就跳過了檢查版本。具體看個人需求,比如不想讓用戶繼續用舊版本的主體程序,強制要求用戶從自更程序exe啟動的話,也可以隱藏或者通過重命名主體程序exe的方式不讓用戶能點擊,再在自更程序中啟動主體程序。

2、VS編輯器中將自動更新程序設為軟件啟動項(開發完自更程序后再切回去即可,因為在開發階段不希望每次啟動都先運行自更程序嘛)。新建一個Program類寫上Main()函數作為項目運行入口。啟動項目時,執行自動更新程序的Main()函數,先檢查自動更新程序其自身是否需要更新!檢查自更程序編譯出來Debug文件夾下的exe文件的版本號如下。

FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(System.Windows.Forms.Application.ExecutablePath); // ExecutablePath = D:\workspace\MyProject\UpdateTool\bin\Debug\UpdateTool.exe
string fileVersions = string.Format("{0}.{1}.{2}.{3}", fileVersionInfo.FileMajorPart, fileVersionInfo.FileMinorPart, fileVersionInfo.FileBuildPart, fileVersionInfo.FilePrivatePart);

3、自更程序的Main()函數通過傳參判斷是否其自身是否需要更新。有就下載更新,沒有就不更新。

4、傳遞自更程序的版本到服務端,服務端查數據庫獲取最新版本號(最大版本號 SELECT max(version) FROM update_tool_version),發現當前自更程序不是最新版本,返回最新版本還需下載的文件壓縮包的url路徑。該壓縮包內的文件是新的圖片資源、新版本自更程序exe等。

5、現假設要求先更新自更程序。自更程序的增量內容壓縮包下載到本地的緩存文件夾下。現獲取該文件夾路徑如下。

string cachePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\MyProject"; // C:\\Users\\Administrator\\AppData\\Roaming\\MyProject
DirectoryInfo directoryInfo = new DirectoryInfo(cachePath);
if (!directoryInfo.Exists)
{
    directoryInfo.Create(); // 目標文件夾不存在就創建
}

6、由於當前的自更程序exe已處於運行狀態,該exe文件被占用了,升級包中的UpdateTool.exe是無法覆蓋這個文件的,所以采取的辦法是將UpdateTool.exe拷貝到緩存文件夾中,然后啟動緩存文件夾中的UpdateTool.exe文件來完成升級的過程。

把自更程序exe復制到緩存文件夾,再傳參啟動副本exe,並關閉當前的exe。自更程序在Main()函數中通過判斷傳入的參數,執行下載新版本的邏輯,覆蓋項目路徑下的UpdateTool.exe。

// 先把當前自更程序exe文件考到緩存文件夾中
Process processes = Process.GetCurrentProcess();
string name = processes.ProcessName;
string source = System.Windows.Forms.Application.StartupPath + "\\" + name + ".exe"; // D:\workspace\MyProject\UpdateTool\bin\Debug\UpdateTool.exe
string target = cachePath + "\\" + name + ".exe"; // C:\\Users\Administrator\AppData\Roaming\mjl\UpdateTool.exe
File.Copy(source, target, true);
string arg = System.Windows.Forms.Application.StartupPath; // D:\workspace\MyProject\UpdateTool\bin\Debug
if (!string.IsNullOrEmpty(updateUrl))
{
    arg += ("|" + updateUrl); // D:\workspace\MyProject\UpdateTool\bin\Debug|/assets/file/1518053629860.zip
}
arg = "\"" + arg + "\""; // "D:\workspace\MyProject\UpdateTool\bin\Debug|/assets/file/1518053629860.zip"

// 傳參運行副本自更程序exe,Main()函數通過傳參執行下載新版本的邏輯
ProcessStartInfo info = new ProcessStartInfo(target, arg); 
Process.Start(info);

// 關閉當前的自更程序
Environment.Exit(0);

 7、上面的操作再次啟動自更程序exe時,由於這次Main()函數有傳參,所以執行下載新版本的操作。

// 開始更新自更程序
App app = new App();
UpdateToolView view = new UpdateToolView(args[0]);
app.Run(view); // 觸發UpdateToolView.xaml.cs的構造方法

8、更新自更程序的界面UpdateToolView是一個很簡單的窗體,只有一個ProgressBar進度條展示更新的進度。UpdateToolView的構造方法中通過傳入的args獲取到UpdateTool項目路徑和更新文件的url地址后,用BackgroundWorker類開一個后台線程進行文件下載,邊下載邊更新ProgressBar進度條。

9、下載完成后,解壓縮到UpdateTool項目路徑下。解壓工具類可使用第三方庫ICSharpCode.SharpZipLib.Zip.dll,網上能搜到很多例子,如這里

10、完成解壓后,不傳參啟動該新版本exe,同時退出當前舊版本的自更程序。自此,就已完成更新自更程序到最新版本了。

______ 休息一下 ______

11、上一步不傳參啟動了自更程序后,自更程序Main()函數就不再檢查自更程序的版本,開始檢查主體程序的版本。流程跟上面更新自更程序的步驟幾乎一致。

12、如果主體程序已經是最新版本,則直接啟動主體程序並關閉自更程序。

13、如果主體程序也需要更新,下載、解壓邏輯與上面相似。重下客戶端可能壓縮包會比較大,可先下載到緩存文件夾Roming下再解壓到項目目錄中。如果是增量更新(壓縮包的內容是新增的圖片資源、新增大dll文件等)就不用考慮解壓后項目文件夾重名的問題。

注意:更新主體程序除了要更新Client.exe還要更新配置文件Client.exe.config!如果不能同名覆蓋的話就要先刪除本地舊的config再解壓壓縮包!

14、解壓完成后,閉殘留的主體程序進程,啟動主體程序。

// 關閉殘留的主體程序的進程
public static void CloseAllExe()
{
    Process[] ps = Process.GetProcesses();
    foreach (Process p in ps)
    {
        if (p.ProcessName.Equals("Client") // 主體程序的文件名,根據項目修改。
        {
            p.Kill();
        }
    }
}

// 直接啟動主體程序
ProcessStartInfo info = new ProcessStartInfo(System.Windows.Forms.Application.StartupPath + "\\" + "Client.exe"); // D:\workspace\MyProject\UpdateTool\bin\Debug\Client.exe
Process.Start(info);
Environment.Exit(0);

 


重要參考: https://www.cnblogs.com/hiyz/archive/2012/07/12/2587458.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM