Qt6 Host + Updater 更新方案(2):manifest.json 设计与版本比较规则

在客户端在线更新系统里,流程图并不难画,真正容易踩坑的是“协议”。

如果manifest.json 设计不当,常见问题会集中爆发:

1)版本号比较规则不一致导致误判

2)缺少校验字段导致下载包损坏难以定位

3)强制更新/最低可运行版本策略无法落地

4)后续要做灰度发布、多平台/多架构分发时协议难以兼容扩展

本文基于“Qt6 Host + 独立 Updater” 的更新架构,给出一套可演进的 manifest.json 设计方案,并重点说明版本比较的推荐实现方式。你可以将文中的 manifest 直接部署到 HTTP 服务上,与上一篇的 Check/Apply 更新流程配合使用。

什么是manifest.json?

这里的 manifest.json 指“更新清单(manifest)文件”。

“manifest”本意是清单/声明文件,是行业内常用命名:它不承载更新包本体,而是以一份可通过 HTTP 下发的 JSON 元数据,描述当前可用的最新版本及其发布信息(例如版本号、下载地址、包大小、哈希校验、更新说明、强制更新策略等)。

在本文的体系中,Host 在 Check 阶段读取 manifest.json 以判断是否需要提示更新并更新 UI;独立 Updater 在 Apply 阶段依据同一份 manifest.json 选择下载目标并完成完整性校验与安装执行。

因此,manifest.json 可以视为更新系统的“单一事实来源”(Single Source of Truth):用于将更新策略与发布信息从客户端代码中解耦出来,便于后续运维与扩展。

manifest 设计

设计目标

在定义字段之前,先明确manifest的设计目标。本文的manifest.json需要满足一下几点:

★可用:Host能据此判断是否需要提示更新;Updater能据此完成下载与校验。

★可扩展:后续增加字段不影响旧客户端解析

★可兼容:允许服务端同时服务不同版本客户端

★可校验:更新包必须可校验,避免下载成功但安装失败/跑不起来

字段集合

为了让更新流程先跑通,manifest至少包含以下字段:

version                最新版本号(用于版本比较)
url更新包下载地址(Updater使用)
sha256                        更新包哈希,校验完整性
size更新包大小
changelog更新说明(Host UI展示)

这组字段追求“够用、最少”,不追求一次把所有高级能力(灰度、多平台、多包、强更策略、签名等)都设计进去。先用MVP跑通Demo、验证链路,在逐步加字段扩展,而不会推翻原有协议。

注意:很多人只放 version + url,这会导致“包损坏/被替换”时难以定位问题,工程上建议一开始就加入hash+大小校验更安全。

示例

下面给出一个简单的manifest.json的示例结构:

{
	"id": "e58e228e2b424aed8a826fa04fef90e6",
	"createTime": "2026-01-01 13:23:55",
	"version": "2.1.17.10",
	"sha256": "YOUR_SHA256_HERE",
	"sizeBytes": "445718686",
	"changelog": "显示当前更新包的更新说明内容",
	"updateUrl": "http://10.0.0.16:5000/update/ProjectName/697100a466eb419b8af08ca58f46f669.exe"
}

字段说明与使用阶段

id(可选)

更新包记录的唯一标识,用于日志追踪/服务端审计;客户端一般不参与逻辑判断。

createTime(可选)

发布时间/生成时间,可用于 UI 展示或排查问题,不参与版本比较。

version(必填)

服务器最新版本号。

Host 在 Check 阶段用它与当前版本比较,决定是否显示“升级”标识;Updater 在 Apply 阶段可二次校验避免重复升级。建议明确版本比较规则(本文后续章节说明)。

updateUrl(必填)

更新包下载地址。

Updater 在 Apply 阶段使用该 URL 下载更新包。

sizeBytes(必填)

更新包大小(字节)。

用于下载进度展示与快速完整性校验。

建议用字符串类型而非数字类型,如果文件过大会导致解析json出现错误,当前QJson不会,如果是CJSON就会有些问题了。

sha256(必填)

更新包哈希值。

Updater 下载完成后用于完整性校验,避免“下载成功但包损坏/被替换”导致安装失败或不可启动。

changelog(可选)

显示当前更新包的更新说明,可根据工程要求是否展示到UI上。

版本比较规则

在更新系统中,版本比较必须是一个“确定性规则”,且 Host(Check 阶段)与 Updater(Apply 阶段)必须使用同一套算法。

常见踩坑是直接用字符串比较版本号,例如把1.10.0误判为小于1.2.0。

因此本文明确约定:版本号由若干段十进制整数构成,使用逐段数值比较。

版本号格式约定

在本文Demo中使用四段版本号(与项目规则一致,无论你是纯Qt开发还是VSCode开发):

version:major.minor.patch.build

示例:2.1.17.10

比较原则

将版本字符串按 “.” 拆分为整数数组,按顺序逐段比较:

1)从major开始比较,第一段更大则版本更大

2)若相等,再比较下一段

3)知道某一段出现差异嚯所有段都相等

段数不一致如处理

为了固定规则,如果段数不一致则认为该软件不具备升级功能。

非法版本号处理策略

manifest版本如果出现非法合适(包含字母、空段、段数过大、溢出等),则认为该软件不具备升级功能。

代码示例

bool IsUpdateAvailable(const QString& currentVersion, const QString& lastestVersion)
{
    const QStringList listCurrent = currentVersion.split('.');
    const QStringList listLast = lastestVersion.split('.');
    //基本校验:不是4段就认为不升级
    if (listCurrent.size() != 4 || listLast.size() != 4) {
        return false; //不升级
    }
    for (int i = 0; i < 4; i++) {
        bool bOk1 = false, bOk2 = false;
        const int current = listCurrent[i].toInt(&bOk1);
        const int last = listLast[i].toInt(&bOk2);
        //某段不是纯数字,认为不升级
        if (!bOk1 || !bOk2) {
            return false;
        }
        if (last > current) {
            return true; //远端更新,需要升级
        }
        if (last < current) {
            return false; //当前更高,不升级
        }
    }
    //四段都相等,不升级
    return false;
}

在Check/Apply阶段的使用方式

Check(Host)阶段

若currentVersion < manifest.version ⇒ 显示“升级”标识(可选更新),否则不显示

Apply(Updater)阶段

AppUpdater.exe启动后再次获取/读取manifest,比对currentVersion 与 manifest.version:

若无需升级:直接提示“已是最新版本”并退出

若需要升级:进入下载与安装流程

这样可以避免用户点击后,服务端刚好回滚版本/已更新完成导致重复安装。

总结

本文完成了 manifest.json 的字段约定,并统一了四段版本号(如 2.1.17.10)的比较规则。

有了这份协议,Host 在 Check 阶段就能稳定判断“是否需要提示更新”,Updater 在 Apply 阶段也能按同一份数据完成下载与校验。

下一篇将进入实现层:Qt6 宿主如何异步拉取 manifest、解析字段并更新“升级”标识。

我是糯诺诺米团,一名C++程序媛~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

糯诺诺米团

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值