.NET 程序自动更新的回忆总结

文章目录

前言

不管BS的还是CS 的程序,或者APP,程序更新都是比较痛苦的。

如果要设计出自动更新,那思考的就多了。

代码可维护、性能高效、用户体验好、异步避免UI阻塞、增量更新减少下载量、签名验证保障安全,以及回滚机制处理失败场景

一、 设计

如果有这样的一个议题,设计当前程序的自动更新,那应该怎样处理呢?

  1. 客户端 配置表记录当前版本号。
  2. 管理员 使用客户端上传更新的dll、或者其他文件,更新版本号
  3. 用户 登录的时候检查本地配置、数据库 的版本是否匹配,触发更新。

从逻辑上: 增量更新减少下载量
从数据上:

  • A表 记录当前版本号及更新日期。
  • B表 记录版本号对应的文件

如果不用本地配置记录版本号,还可以将 用户 或 设备MAC 跟版本号在数据库里绑定,作为更新检查依据。

二、核心设计模块

  1. 版本控制机制

    • 采用语义化版本规则:主版本.次版本.修订号(如 2.1.3
    • 兼容性管理:通过 VersionCompatibility 类处理新旧版本兼容性
    csharp 复制代码
    public class VersionCompatibility {
        public bool IsBackwardCompatible(Version oldVer, Version newVer) {
            return (newVer.Major == oldVer.Major) && (newVer.Minor >= oldVer.Minor);
        }
    }
  2. 增量更新策略

    • 差分算法生成增量包(如 BSDiff)
    • 减少 60%-80% 的下载体积
    python 复制代码
    # 生成增量包示例
    import bsdiff4
    bsdiff4.file_diff("v1.0.exe", "v1.1.exe", "patch.diff")

三、多客户端兼容实现

客户端类型 更新方案 关键技术点
WinForm 独立更新服务进程 Windows Installer (MSI)
Web 前端 AJAX 异步更新 Service Worker 缓存控制
跨平台应用 容器化更新包 Docker 镜像分层更新

跨平台更新检测逻辑

javascript 复制代码
// 统一版本检测接口
async function checkUpdate() {
  const res = await fetch("/api/version/latest");
  const { version, url, minRequiredOS } = await res.json();
  if (compareVersions(currentVer, version) < 0) {
    if (checkOSCompatibility(minRequiredOS)) {
      startDownload(url);
    }
  }
}

四、前端交互实现

不管winfrom 还是 vue支持的各种UI。progress进度条都是成熟的控件,能呈现更新状态:

  1. AJAX 进度监控

    javascript 复制代码
    const xhr = new XMLHttpRequest();
    xhr.upload.addEventListener("progress", e => {
      const percent = Math.round((e.loaded / e.total) * 100);
      updateProgressBar(percent); // 更新进度条组件
    });
    xhr.open("POST", "/upload-update");
    xhr.send(formData);
  2. 可视化进度组件

    html 复制代码
    <div class="progress-container">
      <div class="progress-bar" id="update-progress"></div>
      <div class="progress-text">0%</div>
    </div>
    <script>
    function updateProgressBar(percent) {
      document.getElementById("update-progress").style.width = `${percent}%`;
      document.querySelector(".progress-text").innerText = `${percent}%`;
    }
    </script>

五、安全机制

  1. 沙盒验证流程

    通过 失败 下载更新包 沙盒环境解压 签名验证 替换主程序 警报并回滚

  2. 关键安全措施:

    • SHA256 文件校验
    • 代码签名证书验证
    • 更新通道 HTTPS 加密

当然,在BS中我已经习惯使用WebApi作为数据接口,JWT 的签名验证,真的很方便。这在前面的文章里我也有提到过:
WebApi验证JWT爬坑记录

六、实践案例

C# 自动更新服务

csharp 复制代码
public class AutoUpdateService {
    public void CheckAndApplyUpdate() {
        var latest = VersionAPI.GetLatest(); // 调用版本API
        if (latest > CurrentVersion) {
            var downloader = new FileDownloader();
            downloader.ProgressChanged += (p) => UpdateUI(p);
            byte[] updateData = downloader.Download(latest.Url);
            
            if (VerifySignature(updateData)) { // 签名验证
                InstallUpdate(updateData);
            }
        }
    }
}

七、实践补充

作为客户端,分4种情况:

  • 64位 桌面程序
  • 32位 桌面程序
  • 网页
  • APP应用

在桌面程序中,32、64位客户端首先肯定是需要分开上传不同路径,

检测客户端情况再更新的:

csharp 复制代码
///判断是否64位
public static Architecture GetCurrentArchitecture()
{
    return Environment.Is64BitProcess ? Architecture.X64 : Architecture.X86;
}

网页不用考虑,APP却不可增量更新。因为APP的APK包,其实只有一个文件,

不过HBuilder X倒是集成了wgt包的制作,补丁式增量更新,我看了下感觉有点便秘,整不来。

相关推荐
云草桑4 小时前
.net AI MCP 入门 适用于模型上下文协议的 C# SDK 简介(MCP)
ai·c#·.net·mcp
CsharpDev-奶豆哥14 小时前
ASP.NET中for和foreach使用指南
windows·microsoft·c#·asp.net·.net
weixin_456904271 天前
C# 串口通信完整教程 (.NET Framework 4.0)
网络·c#·.net
追逐时光者2 天前
C#/.NET/.NET Core技术前沿周刊 | 第 57 期(2025年10.1-10.12)
后端·.net
INCerry2 天前
.NET周刊【9月第4期 2025-09-28】
.net
曹振华2 天前
.net 6 signalr
.net·signalr
许泽宇的技术分享2 天前
从零到一:基于.NET 9.0构建企业级AI智能体对话平台的实战之旅
人工智能·.net·ai智能体·a2a协议·agent framework
IDOlaoluo2 天前
Microsoft.NET安装步骤详解(.NET Framework/.NET 6/7/8安装教程)
microsoft·.net