自動更新系統包含四大元件:
.zip/.rar 含需更新的檔案(DLL、EXE、設定檔等),放置於伺服器對應路徑。<?xml version="1.0" encoding="utf-8"?>
<Items>
<UpdaterItem>
<Name>V1.0.0.25</Name>
<Version>1.0.0.25</Version>
<Date>2024-01-15T10:30:00</Date>
<Descript>
<string>修正報表匯出錯誤</string>
<string>新增客戶匯入範本</string>
</Descript>
<FileName>releases/1.0.0.25.zip</FileName>
<CloseMain>true</CloseMain>
</UpdaterItem>
<UpdaterItem>
<Name>V1.0.0.26</Name>
<Version>1.0.0.26</Version>
<Date>2024-02-01T09:00:00</Date>
<Descript>
<string>優化資料庫查詢效能</string>
<string>修正多執行緒競爭條件</string>
</Descript>
<FileName>releases/1.0.0.26.zip</FileName>
<CloseMain>true</CloseMain>
</UpdaterItem>
</Items>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="MainExeName" value="MyApp.exe" />
<add key="UseConfigVersion" value="true" />
<add key="ServerUrl" value="https://update.mydomain.com/" />
<add key="UpdaterXml" value="Updater.xml" />
<add key="CurrentVersion" value="1.0.0.24" />
<add key="BlockSize" value="8192" />
</appSettings>
</configuration>
using FaibClass.Update;
using System.Reflection;
using System.Windows.Forms;
public static class AutoUpdater
{
public static void CheckAndUpdate()
{
try
{
var updater = new Updater(Assembly.GetExecutingAssembly());
if (updater.CheckUpdate())
{
if (MessageBox.Show("發現新版本,是否立即更新?", "自動更新",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
updater.BeginUpdate(); // 啟動 UpdaterExc.exe 並關閉主程式
Application.Exit();
}
}
else
{
// 自動更新更新器本體
SelfUpdateUpdater();
}
}
catch (Exception ex)
{
Log.Error("自動更新檢查失敗", ex);
}
}
private static void SelfUpdateUpdater()
{
string newExe = Path.Combine(Application.StartupPath, "UpdaterExc.exc"); // 臨時副檔名
string oldExe = Path.Combine(Application.StartupPath, "UpdaterExc.exe");
if (File.Exists(newExe))
File.Replace(newExe, oldExe, null, true); // 原子替換
}
}
Updater.xml,比對本地版本,建立待更新清單。| 挑戰 | 解決方案 |
|---|---|
| 主程式執行中無法覆蓋 EXE/DLL | 由獨立 UpdaterExc 執行更新,主程式已退出 |
| 更新過程中斷電/網路中斷 | 採用「備份→複製→驗證→提交」原子操作,失敗可回滾 |
| 多版本累積更新 | Updater.xml 含所有歷史版本,客戶端按順序逐版套用 |
| 更新器自身更新 | 下載為 .exc 副檔名,完成後 File.Replace 原子替換 |
| 權限不足(Program Files) | UpdaterExc 以管理員權限啟動(manifest requireAdministrator) |
| 簽名驗證 | 下載後驗證 SHA256/數位簽章,防止中間人攻擊 |
HttpClient + System.IO.Compression + Process.Start 重啟,完全自主可控。自動更新框架核心在於主程式與更新器分離、版本清單驅動增量更新、原子替換保證一致性。本文提供傳統 WinForms 架構完整設計,包含伺服器 XML 結構、客戶端配置、主程式整合、更新器流程與關鍵技術細節。現代專案建議評估 Squirrel.Windows 或平台原生部署工具,減少自建維護成本。