博客 / 詳情

返回

基於 JSON 配置的 .NET 桌面應用自動更新方案

前言

在軟件開發和維護過程中,程序更新一直是個繞不開的話題。一開始用最簡單的方式——讓用户手動下載新版本覆蓋安裝,但隨着用户量增加、功能迭代加快,這種方式不僅效率低,還容易出錯。一個輕量、可靠、配置靈活的自動更新機制變得尤為重要。

本文介紹一個簡單可靠的 Windows 程序自動更新實用小工具,它不追求複雜的功能,而是專注於解決"如何讓程序安靜又穩妥地完成自我升級"這個問題。

項目介紹

一個基於 .NET 開發的輕量級程序更新框架,核心由兩個部分組成:主程序集成邏輯 + 獨立的升級執行程序(Upgrade.exe)。

它的設計思路很簡單:每次啓動主程序時,先檢查是否有新版本;如果有,就調用 Upgrade.exe 完成文件替換,再重新啓動主程序。整個過程對用户透明,且通過 JSON 配置驅動,無需硬編碼更新地址或文件列表。

項目功能

主要功能圍繞"對比—下載—替換—重啓"展開

通過本地與服務器上的 UpLoadVersion.json 文件比對版本差異;

自動下載服務器上指定的更新文件(支持任意數量);

支持自動更新(IsAutoUpLoad=true)或手動確認更新;

更新完成後自動啓動目標程序(可由配置指定,也可由主程序傳入路徑);

避免重複檢測:升級失敗或無更新時生成 NoUpgrade.ini,防止頻繁彈窗。

項目特點

這個方案最大的特點是"輕"和"穩"。

它不需要數據庫、不需要後台服務,只依賴一個 JSON 文件和一個獨立的升級程序。配置完全外置,運維人員只需更新服務器上的 JSON 和文件,就能觸發客户端升級。

同時,它巧妙利用環境變量判斷是否在 Visual Studio 中調試,避免開發階段誤觸發更新。

另外,通過傳入主程序路徑的方式,使得 ProgrmStartupDir 字段甚至可以留空,提升了靈活性。

項目使用

可以通過 JSON 文件進行更新和打開程序的一個更新程序。

UpLoadVersion.json 配置説明

UpLoadVersion.json 需要同時放置在程序安裝目錄和服務器更新目錄中,是用於版本對比和更新控制的核心配置文件。

{
  "UpLoadContent": "更新提示內容",
  "UpLoadFileUrl": "更新的地址(帶輸出目錄的網站地址),例:http://localhost:8888/",
  "ProgrmStartupDir": "更新完成後需要運行的程序",
  "IsAutoUpLoad": true,
  "UpLoadFiles": []
}

字段説明

  • UpLoadContent:更新時向用户展示的提示文本。

  • UpLoadFileUrl:服務器上更新文件所在的根 URL,需以 / 結尾。

  • ProgrmStartupDir:更新完成後要啓動的程序路徑(可為空,若啓動 Upgrade.exe 時傳入主程序路徑,則優先使用傳入值)。

  • IsAutoUpLoad:是否自動更新,設為 true 則無需用户點擊確認。

  • UpLoadFiles:包含待更新文件信息的數組,每項記錄文件名及其 MD5 值,用於比對是否需要下載。

IIS 發佈配置

1、添加網站,物理路徑指向你的最新程序更新目錄。

2、若訪問時出現 403 錯誤,請在 IIS 管理器中進入該網站 → 功能視圖 → "目錄瀏覽" → 點擊右側"啓用"。

生成服務器端 UpLoadVersion.json

UpLoadDemoXmlBuild.exe 複製到待發布的程序目錄中,運行後點擊"生成"按鈕,即可自動生成包含所有文件 MD5 的 UpLoadVersion.json

C# 調用示例

將以下代碼放入 Program.cs 或 WPF 應用的 OnStartup 方法中:

string vsVersion = Environment.GetEnvironmentVariable("VisualStudioVersion");
if (string.IsNullOrEmpty(vsVersion))
{
    string upIni = AppDomain.CurrentDomain.BaseDirectory + "NoUpgrade.ini";
    if (!System.IO.File.Exists(upIni) && System.IO.File.Exists(AppDomain.CurrentDomain.BaseDirectory + "Upgrade.exe"))
    {
        Process.Start(AppDomain.CurrentDomain.BaseDirectory + "Upgrade.exe", 
                      System.Reflection.Assembly.GetExecutingAssembly().Location);
        Environment.Exit(0);
    }
    System.IO.File.Delete(upIni);
}

邏輯説明

  • 通過 VisualStudioVersion 環境變量判斷是否處於調試狀態,避免開發時觸發更新。

  • 若存在 NoUpgrade.ini,表示上次檢測無更新,跳過本次檢查。

  • 啓動 Upgrade.exe 時傳入當前主程序路徑,作為更新完成後的啓動目標。

  • 檢測結束後刪除 NoUpgrade.ini,確保下次啓動仍能檢查更新。

測試更新流程

1、初始狀態下,本地無更新文件。

2、運行程序,若檢測到服務器版本更新,則彈出提示(若 IsAutoUpLoad=true 則自動開始)。

3、下載完成後,Upgrade.exe 自動關閉,並啓動配置中指定或傳入的主程序。

4、更新後,本地的 UpLoadVersion.json 內容與服務器完全一致。

項目代碼

自動更新

private void UpLoadExcute(object obj)
{
    Thread thread = new Thread(()=>{
        if (obj!=null&&obj is System.Windows.Controls.FlowDocumentScrollViewer)
        {
            var uartDataFlowDocument = obj as System.Windows.Controls.FlowDocumentScrollViewer;
           MsgScrollViewer = uartDataFlowDocument.Template.FindName("PART_ContentHost", uartDataFlowDocument) as System.Windows.Controls.ScrollViewer;
        }
        BtnIsEnabled = false;
        ProgressBarVisiblity = Visibility.Visible;
        BtnName = "正在更新...";
        ContentTitle = "更新信息:";
        UpLoadContent = "\r\n";
        AppendMsg("正在比對本地系統與服務器的版本信息。");
        
        ProgressBarValue = 4;
        AppendMsg("需要更新"+ StaticModel.UpLoads.Count+"個文件!");
        UpLoadDown(StaticModel.UpLoads);
        AppendMsg("正在重新啓動程序...");
        Thread.Sleep(2000);
        //升級成功後刪除不檢測升級的文件
        File.Delete(AppDomain.CurrentDomain.BaseDirectory + "NoUpgrade.ini");
        if (!string.IsNullOrEmpty(StaticModel.MyUpLoadModel.ProgrmStartupDir))
        {
            Process.Start(StaticModel.MyUpLoadModel.ProgrmStartupDir);
            Application.Current.Dispatcher.Invoke(new Action(() =>
            {
                Environment.Exit(0);
            }));
        }
        else {
            AppendMsg("沒有找到要啓動的程序路徑...");
        }
        //BtnIsEnabled = true;
        //BtnName = "立 即 更 新";
    });
    thread.IsBackground = false;
    thread.Start();
}

項目源碼

Gitee:https://gitee.com/sageinqi/UpLoadDemo

總結

本項目不是一個炫技型的框架,而是一個"解決問題就好"的務實工具。它沒有複雜的 UI,也不依賴雲服務,卻能有效支撐中小型桌面應用的持續交付需求。

對於那些不想引入 Electron autoUpdater 或商業更新服務的 .NET 團隊來説,這種基於文件比對 + JSON 配置的方案,既可控又易於維護。更重要的是,它把更新邏輯從主業務中剝離出來,降低了耦合度,也讓後續擴展(比如加簽名驗證、差分更新)成為可能。

關鍵詞

自動更新、JSON配置、MD5校驗、Upgrade.exe、IIS部署、.NET桌面應用、輕量級、程序升級、文件同步、無侵入

最後

如果你覺得這篇文章對你有幫助,不妨點個贊支持一下!你的支持是我繼續分享知識的動力。如果有任何疑問或需要進一步的幫助,歡迎隨時留言。

也可以加入微信公眾號[DotNet技術匠] 社區,與其他熱愛技術的同行一起交流心得,共同成長!

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.