PrismQML 自动更新接入¶
PrismQML 的自动更新由两层组成:Python Updater 负责读取 GitHub Latest Release、版本比较、安全下载和启动安装器;QML AutoUpdater 负责更新确认、下载反馈和安装交接。应用不应重复实现网络、进度 Toast 或安装器启动逻辑。
完整流程为:
检查 Latest Release
→ 发现新版并确认
→ 下载同平台安装资产
→ 同一反馈控件原位刷新进度
→ 校验 SHA-256
→ 按安装策略交接
→ `in_place`:启动安装器并退出当前应用
→ `dual_slot`:后台写入非活动槽,当前应用继续运行
→ 下次启动自动切换到新版
1. 发布资产约定¶
Updater 默认读取 OWNER/REPO 的 GitHub Latest Release。Release 必须满足:
- tag 可与当前版本比较,例如
v1.2.3; - Release 已公开,且不是草稿或预发布;
- 包含当前平台可执行的资产:Windows
.exe、macOS.dmg/.pkg、Linux.AppImage/.run/.deb; - 资产名包含应用配置的关键词,例如
ExampleApp-Setup-1.2.3.exe包含默认关键词Setup; - GitHub API 返回资产的
sha256:<64位十六进制>digest。PrismQML 默认要求摘要,并在下载完成后再次校验。
如果没有匹配的当前平台资产,更新确认后会打开 Release 页面,而不会把任意文件当成安装器。
2. 注入 Python 更新后端¶
使用 App 时,在创建 App 后、加载消费 appUpdater 的 QML 前调用 enable_auto_update():
from prismqml import App
CURRENT_VERSION = "v1.2.3"
UPDATE_REPOSITORY = "OWNER/REPO"
UPDATE_ASSET_KEYWORD = "Setup"
app = App()
app.enable_auto_update(
UPDATE_REPOSITORY,
CURRENT_VERSION,
UPDATE_ASSET_KEYWORD,
install_strategy="dual_slot",
)
# 继续创建窗口、加载页面并调用 app.exec()。
该调用创建 Updater,强制启用 Release 资产摘要校验,并以 appUpdater 注入 QML 根上下文。dual_slot 会让本次运行继续使用旧槽,安装完成后由启动入口自动切到新槽。应用通常不需要直接连接底层信号。
自行创建 QQmlApplicationEngine 时,可以显式创建 Updater 并注入同名上下文属性;初始化 QML 环境和注册类型仍由宿主负责:
from prismqml import Updater
updater = Updater("OWNER/REPO", "v1.2.3", "Setup", install_strategy="dual_slot")
updater.set_require_artifact_digest(True)
engine.rootContext().setContextProperty("appUpdater", updater)
必须让 Python 持有 updater,直至应用退出。
3. 接入 QML 门面¶
默认 Presenter 是右下角 Toast。一个应用窗口只创建一个 AutoUpdater:
import QtQuick
import PrismQML as Fluent
Item {
id: root
Fluent.AutoUpdater {
id: autoUpdater
updater: appUpdater
autoDownload: true
notifyWhenUpToDate: true
silentArgs: Qt.platform.os === "windows"
? "/SILENT /SUPPRESSMSGBOXES /NORESTART /SP-"
: ""
}
Timer {
interval: Fluent.Enums.duration.toast
running: true
repeat: false
onTriggered: autoUpdater.checkSilently()
}
Fluent.Button {
text: "检查更新"
onClicked: autoUpdater.check()
}
}
check() 是可见的手动检查;当 notifyWhenUpToDate=true 时,已是最新版也会显示反馈。checkSilently() 用于启动检查,不显示“正在检查”、已是最新版或检查失败 Toast;如果确实发现新版,仍会打开更新确认框。
下载开始后,默认 Toast Presenter 只创建一次反馈对象。后续进度通过属性更新同一对象,不会每次收到进度信号都重新弹 Toast:
服务端尚未提供总大小时显示不确定进度和已下载字节;首次获得有效总大小后自动切换为确定进度。
4. 切换进度展示器¶
需要模态进度窗口时,将 feedbackPresenter 换成 AutoUpdaterProgressDialogPresenter:
Component {
id: updateProgressPresenter
Fluent.AutoUpdaterProgressDialogPresenter {}
}
Fluent.AutoUpdater {
updater: appUpdater
feedbackPresenter: updateProgressPresenter
}
需要恢复 Toast 时使用 AutoUpdaterToastPresenter。不要在业务层同时监听下载信号再创建第二套 Toast,否则会产生重复反馈。
5. Windows 安装器模板¶
先复制 安装器示例清单,为应用固定 app_id、aumid、安装范围和 Nuitka standalone 目录。需要双槽替换安装时,将:
若仍使用 in_place 并要求安装后立即重启,新安装清单可设 launch_after_install=true;双槽已有安装不会在本次会话启动新版。
然后按同一应用版本生成并检查 Inno Setup 脚本:
prismqml-installer generate --manifest prismqml-installer.json --version 1.2.4 --output installer.iss
prismqml-installer check --manifest prismqml-installer.json --version 1.2.4 --output installer.iss
prismqml-installer doctor --manifest prismqml-installer.json
完整字段和编译命令见 Windows 安装器模板。生成结果会使用:
CloseApplications=no(双槽):不关闭当前应用,完整写入非活动槽;RestartApplications=no:不让 Restart Manager 再启动一次,避免双开;prism-update-slot.ini:记录下次启动目标槽;App启动重定向:旧快捷方式/任务栏入口也会自动进入目标槽;- 稳定
AppId:新版覆盖同一安装,而不是创建第二个应用。
6. 安装参数选择¶
Windows 运行参数由应用传给 AutoUpdater.silentArgs:
| 参数 | 用户看到的效果 | 推荐场景 |
|---|---|---|
| 空字符串 | 完整 Inno Setup 向导 | 需要用户逐步选择 |
/SILENT /SUPPRESSMSGBOXES /NORESTART /SP- |
隐藏向导,但显示安装进度窗口 | 默认自动更新体验 |
/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- |
向导和安装进度窗口都隐藏 | 确实需要完全无界面安装 |
机器级安装仍可能显示 Windows UAC 提示,这是操作系统安全边界。双槽更新不使用 /RESTARTAPPLICATIONS 或 /AUTORESTARTAPP,也不会在本次运行中重启应用。
7. 端到端验收¶
源码测试不能代替打包安装验收。正式发布至少验证:
- 版本号、Release tag、安装器文件名与安装后 EXE 产品版本一致;
- 安装器脚本
check无漂移; - 在一次性 Windows runner 上运行 Nuitka 和 ISCC;
- 使用与应用相同的
/SILENT参数安装到隔离目录,并保留安装日志; - 核对安装退出码、卸载注册信息、安装目录和产品版本;
dual_slot时确认旧进程仍可操作、非活动槽完整写入,随后从旧快捷方式启动并自动跳转新版;- 结束自动启动的进程,再从安装目录执行 packaged SELFTEST;
- 只有全部通过后,才把安装包附加到公开 Release。
用户侧升级验收应使用两个真实版本:先安装旧版,再发布新版并执行手动检查。确认启动检查不弹 Toast、手动检查有反馈、下载显示 xx MB / xx MB、同一 Toast 原位刷新、应用退出后出现安装进度窗口、安装完成后自动启动且版本已更新。
8. 常见问题¶
| 现象 | 检查项 |
|---|---|
| 启动时弹“正在检查”Toast | 启动入口是否调用 checkSilently(),而不是 check() |
| 每次进度都重弹 Toast | 是否创建了多个 AutoUpdater,或业务层另建了一套下载 Toast |
| 只有已下载大小,没有总大小 | 服务器是否返回有效的下载总长度;获得总长度后会自动切换 |
| 找到新版但没有安装包 | Release 资产后缀或 asset_keyword 是否匹配当前平台 |
| 报资产摘要缺失或校验失败 | GitHub API 的资产 digest 是否存在且与下载内容一致 |
| 安装时完全没有进度窗口 | 是否误用了 /VERYSILENT;需要进度窗口时改为 /SILENT |
| 双槽安装后仍进入旧版 | 检查 prism-update-slot.ini 的 LaunchSlot、目标槽 EXE 和 App 是否使用默认槽重定向 |
| 安装后启动两次 | 是否同时启用了 Restart Manager 重启和 [Run] postinstall |
Gallery 的真实/DRY 演示见 examples/pages/AutoUpdatePage.qml;DRY 模式会模拟双槽准备与下次启动切换,不访问网络、创建文件或启动安装器。