Windows 安装、签名与更新
状态与范围
章节“状态与范围”已批准方案及实施阶段,调研日期为 2026-10-03。 维护者优先选择免费开源签名,并接受以 SignPath Foundation 作为证书发布者。未签名 Inno 安装器、C# NativeAOT 启动器/部署日志、Manager 生命周期锁和签名政策测试现已实现,标签打包已采用明确的第 2 版 Setup/便携技术预览契约。安装器预览记录命令、修复边界与暂存残留。干净客户端/原生交互、更广恢复和版本保留验收仍待完成。Foundation 申请已于 2026-10-04 提交,等待服务方审核,生产签名和已启用更新源/客户端仍待完成。以下要求不表示所有阶段均已通过。
当前产品是面向 Windows 11 24H2 x64 的非打包、自包含 WinUI 3/C# Manager,以及独立 Rust Runner。日常 CI、版本标签发行及手动便携包构建已经实现。已有行为见当前分发方式;本文细化路线图的 P1–P3,不代表其复选框已经完成。
推荐组件
章节“推荐组件”| 领域 | 方案 | 原因与边界 |
|---|---|---|
| 安装器 | 固定版本的 Inno Setup 7.1.0 x64,每用户 EXE | 熟悉的英语/简体中文向导,离线完整载荷,日常安装无需提权 |
| Manager 部署 | 一个小型 C# 部署组件、稳定的 Manager 启动器及完整版本目录 | 安装器与更新器共用激活/恢复协议;不添加 Rust 管理层或新 UI 框架 |
| 公开代码签名 | 向 SignPath Foundation 申请 | 符合免费 OSS 偏好;申请审核与签名批准仍是外部依赖 |
| 更新发现 | Application 中的 C# 服务,使用独立签名的渠道索引 | 只在 Manager 中工作,默认关闭,不上传账号或游戏库 |
| 应用更新 | 经用户确认后调用同一个已验证安装器 | 统一安装路径;首版不做差分补丁或 ZIP 自我覆盖 |
| 便携用户 | 保留完整 ZIP,提供检查与下载指引 | 不自动替换任意解压目录 |
微软支持将完整的非打包、自包含目录放入自定义安装器。.NET 与 Windows App SDK 依赖都必须包含;WinUI 单文件可执行程序不是本方案的交付目标。微软部署指南。
Inno 7.1.0 x64 已固定在 packaging/windows/inno-toolchain.json,工具脚本验证官方下载摘要及发布者后安装到忽略的 target/toolchain。继续支持直接命令,mise 提供可选别名。官方下载。
如有企业部署需求,再考虑 WiX/MSI/Burn。MSIX/Store 需要单独验证包身份、共享数据和卸载行为。Velopack 保留为备选实验:其默认目录可能与现有数据根目录冲突,Windows 更新器也可能尝试终止锁定当前目录的进程。它不能代替我们的数据、Runner、信任和进程策略。Velopack Windows 生命周期。
安装布局与所有权
章节“安装布局与所有权”发布安装器前先确定最终布局,避免加入应用更新时再次迁移:
%LOCALAPPDATA%\Programs\SteamWrapper\ SteamWrapper.exe # 已实现的 Manager 专用启动器 installation.json # 已验证的当前/上一安装状态 versions\<release-tag>\ # 一个完整、不可变的 Manager 目录 SteamWrapper.Manager.exe ...运行时、原生及本地化资源... Runner\SteamWrapperRunner.exe # 随包资源,不是 Steam 的启动目标
%LOCALAPPDATA%\SteamWrapper\ profiles.toml ui-settings.json bin\SteamWrapperRunner.exe # 不变的稳定 Steam 启动目标 updates\trust-state.json # 保留序号/摘要/时钟状态;仅更新底层使用 logs\, backups\, cache\ cache\updates\<transaction>\ # 拟议的受限下载/辅助程序工作区新启动器只启动 Manager。它不会出现在 Steam 启动项中;日常游戏仍使用稳定的 Rust Runner,无需 Manager、启动器、更新器或联网检查。安装状态与游戏配置、界面偏好分开保存。
首版安装器使用固定的每用户程序根目录、恒定 AppId、当前用户卸载注册项及开始菜单快捷方式。桌面快捷方式可选;不添加服务、计划任务、开机启动项或 HKLM 写入。快捷方式指向稳定启动器;Manager 保持一致的 AppUserModelID,以保留任务栏固定项。自定义安装目录留待以后,并需验证所有权和路径。
设置 PrivilegesRequired=lowest、CloseApplications=no 和 RestartApplications=no。安装/更新请求已有 Manager 实例完成保存并正常退出,绝不强杀它们或游戏。Inno 默认的应用关闭行为不符合本项目策略,静默模式也不例外。权限、应用关闭。
首版目标限制为真实 Windows 11 24H2 x64;ARM64 仿真和更早的 Windows 是独立目标。安装、恢复和卸载文本需同时提供完整英语/简体中文,并包含标准图标、许可证/声明材料,以及保留数据的清晰说明。
统一部署事务
章节“统一部署事务”已实现的源码边界为:packaging/windows/ 保存 Inno 定义,apps/deployment-windows/ 保存共享 C# 部署逻辑和 NativeAOT 启动器/辅助程序,恢复时无需加载被替换的 Manager。完整版本清理、跨实例正常退出请求、注册表/快捷方式/断电整体恢复仍属开发或验收工作;预览版拒绝占用中的操作,提示用户正常关闭 Manager。
Inno 管理安装/卸载入口、注册项及快捷方式,并将输入文件解压到临时工作区。部署组件拥有稳定启动器及清单跟踪的暂存/版本目录。Inno 的 [Files] 卸载日志不会自动跟踪其他进程重命名后的暂存目录,不能依靠它删除转为正式版本的目录。安装与卸载钩子必须明确向共享组件交接所有权和锁的生命周期,包括注册项/快捷方式失败时的处理。
安装器、手动修复和应用更新调用同一个部署协议;卸载遵守其所有权与独占锁规则:
- 验证选定安装包、版本、已安装文件所有权及兼容的部署协议。修改前检查磁盘空间,拒绝不安全根目录或重解析点。
- 将完整新载荷写入同一卷上的全新暂存目录。验证每个声明文件、本地化资源、运行时、随包 Runner 及最终已签名字节摘要。保持当前版本不变。
- 激活前取得每用户独占安装锁。启动器与所有 Manager 实例从最早启动阶段到正常退出都参与此锁协议。激活期间阻止新 Manager 启动,并等待已有实例及配置/设置写入结束。只检查一次互斥量仍存在竞态。
- 写入大小受限的事务日志,将已验证目录转为正式版本,并原子替换安装状态文件中的当前/上一版本。只有部署组件写入此状态;Inno 和更新器不另行实现独立引擎。
- 释放安装锁,通过启动器启动 Manager。正常初始化后接收与本次事务绑定的健康确认,不自动迁移配置。
- 通过独立的短期写入锁,在本次事务绑定的日志记录中标记健康;这既不改变当前版本指针,也不将新 Manager 生命周期内持有的共享锁升级为独占锁。需要独占安装锁的清理/压缩延后至下一个安全时机。只有成功激活后,才清理清单明确归属的旧程序文件,并按文档规定的磁盘策略至少保留一个可用旧版本及已验证的修复路径。
原子替换一个状态文件,不能证明整个安装器、注册表、快捷方式和断电事务均具备原子性。事务日志恢复、首次安装与启动器自身更新必须有真实故障测试。启动器运行时无法被替换;应拒绝/延后,不安排重启时强制替换。更新辅助程序从已验证的独立缓存位置运行,避免覆盖自身可执行程序。
若新 Manager 在健康确认前退出,只有重新取得独占锁并确认数据/Runner 兼容后才能恢复上一版本指针。仍在运行但启动较慢的 Manager 不代表失败:报告超时并提供恢复入口,不终止它,也不自动启动与其竞争的另一版本。首版可以承诺已验证的手动恢复;无人值守启动回滚是以后需要独立证据的能力。
稳定 Runner 与卸载
章节“稳定 Runner 与卸载”安装器拥有随包资源,不拥有稳定 Runner 或数据目录。现有 C# RunnerInstaller 继续负责共享 Runner 安装、清单/哈希识别及原子二进制替换。Manager 安装本身不写 Steam 启动项。
旧 Runner 与配置契约兼容时,只更新 Manager 可以在游戏继续运行期间进行。稳定 Runner 的替换应延后至安全时机,不为释放其文件而强杀游戏。当前安装服务具备文件占用处理,但没有完整的启动与更新生命周期协议。宣称可协调这两者前,应增加经过测试的跨进程 Runner 锁协议,并保留旧受支持 Runner 及其恢复行为。旧 Runner 不参与新增锁协议:在该兼容阶段仍保留原子替换及 Windows 对占用文件的拒绝行为,不能仅因升级 Manager 就宣称协调没有竞态。不兼容时阻止安装,或要求独立审核的迁移;首版更新器只支持现有配置/CLI 契约。
默认卸载只删除归属明确的 Manager 版本、启动器、快捷方式及卸载注册项。卸载取得同一个独占安装锁,请求 Manager 正常退出,并阻止新启动,直至归属明确的文件删除及 Inno 注册项/快捷方式移除全部完成。已验证的卸载辅助程序运行在待删除目录之外;测试 Inno/辅助程序之间锁的交接,不只做一次进程检查。保留配置、设置、稳定 Runner、更新信任状态、日志、备份和缓存。首版不添加“删除全部内容”复选框:安全自动恢复 Steam 启动项尚未实现,也无法证明所有手动粘贴的引用已经消失。提供独立的手动移除指引。卸载只删除已跟踪/清单声明的文件,绝不递归清空任意用户选择的目录。Inno 卸载删除指引。
便携版迁移为安装版时,不复制游戏文件,并保留现有数据/稳定路径。修复应保留未知数据及更新且兼容的 Runner;迁移位置、任务栏固定项及仅卸载 Manager 后重新安装分别验收。
SignPath 申请与发行信任
章节“SignPath 申请与发行信任”申请前准备真实公开的 WinUI 安装器预览:另一实现的历史发行不能证明当前申请形式。审核实际发布的依赖清单及适用 notices/许可证,记录产品行为、作者/审核者/批准者、MFA 及双语代码签名/隐私政策。Foundation 资格和批准并无保证。其条款要求自有代码构建可追溯、发行签名由人工批准;第三方运行时文件保留上游签名。申请须确认 Microsoft 系统运行时例外,不能把全部随包依赖描述为 MIT。Foundation 条件、申请。
维护者接受 Foundation 作为发布者。批准前不能宣传已经获得证书。有效签名不代表 Defender、SmartScreen 或 Smart App Control 一定接受每个新产物;仍需在正常启用防护的环境中进行下载/启动测试。EV 不提供自动绕过 SmartScreen 的能力。微软 SmartScreen 指引。
使用 SignPath 服务适配层,在受保护的发行环境中保存最小权限提交令牌,并在 SignPath 完成批准。PR/main CI 与普通手动预览不得访问生产签名。签名只接受经过审核的主线版本标签,并绑定 GitHub 托管构建、源码提交和已上传产物身份;自行填写的 JSON 来源声明不足以证明构建来源。接入时确认服务兼容多阶段串联签名。SignPath GitHub 来源验证。
只有维护者符合其法律身份资格时,Azure Artifact Signing 才是可选后备;在其他区域创建 Azure 资源不等于身份获批。付费 CA/HSM 方案需要单独决定预算。所选免费优先方案不依赖这两者。微软资格条件。
签名顺序与版本规则
章节“签名顺序与版本规则”未来已签名发行的顺序为:
审核标签并重跑全部门槛→ 构建完整 Manager/Runner/部署载荷,并准备 Inno 卸载程序模板→ 签自有 PE 文件及卸载程序模板,验证时间戳与 Windows 信任→ 用最终已签名 Runner 字节重新生成 Runner 清单→ 从保持不变的已验证载荷构建 ZIP 和 Setup→ 签最终 Setup 可执行程序→ 检查已安装/归档载荷、签名及所有最终摘要→ 生成发行元数据/校验和,并独立签更新元数据→ 上传并下载核验不可变产物,发布 Release,再更新渠道索引载荷/卸载程序模板与最终安装器是独立签名阶段;Foundation 可能要求不止一次批准。接入时确认服务接受 Inno 生成模板的构建来源及第二次签名请求,不依赖经过审核的构建之外人工签出的二进制文件。不能假设一次嵌套签名请求可以在 Runner 清单封存后继续改变 Runner 字节。Inno 嵌入卸载器前先完成签名,保留其本地化消息文件,并验证安装后的签名。Inno 已签名卸载器。
采用 SHA-256 与可信 RFC3161 时间戳,验证 Windows Authenticode 及预期身份;缺少时间戳或出现警告都作为签名门槛失败。绝不以项目身份重新签第三方运行时。ZIP 是容器:签其中自有 PE 文件,通过独立签名元数据绑定 ZIP 的最终摘要;不称其为 Authenticode 签名 ZIP。微软 SignTool。
应用自行执行离线验证时,使用 WinVerifyTrust 的 WTD_CACHE_ONLY_URL_RETRIEVAL;仅禁用吊销检查不能阻止其他证书获取请求。缓存信任不代表吊销状态是最新的。缺少可信证书链/时间戳证据时,验证失败并说明修复/离线问题,不接受不可信安装包。明确授权更新期间的在线吊销验证可能独立于 GitHub 产物请求,联系证书颁发机构端点;应记录受限超时及无法访问/已吊销的处理结果。Runner 或普通离线 Manager 启动均不发起此类查询。操作系统自身的检查和警告与应用请求分开看待。微软信任标志。
未签名发布流程在签名前计算 Runner SHA-256。Runner 现有已测试的 Windows PE 元数据,当前自有 C#/Rust 源码产品与未签名技术安装器采用协调的 0.2.4 版本,不追加 SDK 提交后缀。之前 0.2.1 的 PE 验证和真实 0.2.1 → 0.2.2 升级/回滚保留为有日期的证据。WindowsSigning.ps1 可验证最终已签名 Runner 字节并原子重建暂存清单,但尚未连接生产签名服务。D3 仍需接入签名顺序并检查每个自有 PE/模板;不执行未知已安装文件来获取版本。源码提交保留在发行元数据中。RunnerInstaller 比较三段数字版本,同版本不同摘要拒绝覆盖,所以首次新签名载荷需采用未签名 0.2.4 之后尚未使用的协调基础版本,至少为 0.2.5。
首个已签名系列保持各产品数字版本协调一致,每次重新构建/签名发行都递增基础版本。例如,不能为 v0.2.1-preview.1 和 v0.2.1-preview.2 重新签出不同的 Runner 字节,却仍将两者都标为 0.2.1。引入签名时使用尚未发布的新基础版本;不重新签已有公开标签。重试失败的发布任务时复用完全相同的不可变已签名产物。以后可以设计独立组件契约/版本及复用未变更的已签名 Runner,但需明确兼容性元数据并采用服务方批准的产物策略,不能违反统一产品版本限制,也不能简单删除版本门槛。
可选更新行为与认证
章节“可选更新行为与认证”先提供可见的检查更新操作。默认关闭自动检查。明确偏好可允许 Manager 打开期间定期检查;自动下载是独立选项,应用更新始终需要确认。关闭时取消工作。不添加服务、开机任务、常驻托盘进程、Runner 请求、游戏更新或游戏数据上传。界面/偏好/错误需完整提供两种语言,并保留已有设置中的未知字段。
使用分别签名的稳定/预览渠道索引。默认渠道跟随已安装发行类型;稳定版不能静默切换为预览版。当前 WinUI 仍是预览,因此稳定索引不能暗示已有稳定 WinUI 交付。安装前显示版本、渠道、变更、大小和来源。拒绝更新、离线或元数据过旧时,配置与 Steam 启动仍可使用。
拟议索引绑定应用 ID、平台/最低系统版本、渠道、SemVer/数字组件版本、源码提交、配置/Runner/部署兼容性、产物 URL 和最终 SHA-256/长度、递增渠道序号、签发与过期时间。对精确 UTF-8 字节验证分离签名后,再执行严格拒绝重复键的 JSON 解析。内置由项目控制的更新信任根;不能因证书 Subject 相同,就接受另一个合法 Foundation 签名的无关程序。
首版 ECDSA P-256 元数据签名适配层可使用 .NET 密码学和独立保护的发行密钥;它不是 Foundation 的 Authenticode 私钥。定义密钥 ID、格式、由已有信任授权的轮换方式,以及密钥丢失/泄露恢复方案。每个渠道已接受的最高序号、精确索引摘要及其时钟状态,原子保存到保留的 updates/trust-state.json,放在可清理下载缓存之外。同序号且摘要相同允许重试;较旧序号或同序号不同字节拒绝。清理缓存及默认 Manager 卸载不会重置此状态。元数据过期或时钟回拨/不确定时,报告无法确认新鲜度,不显示“已是最新”;这些情况阻止更新,不影响离线配置或 Steam 启动。这些是选定的更新安全要求,不代表完整实现 TUF 规范。TUF 元数据模型。
发现索引发布到独立、受保护的生成元数据分支,从固定的官方 GitHub URL 读取;不让发行任务将生成更新源提交进 main 或重新部署文档。该分支不是开发源码,也不触发应用构建。只有发行产物已经可用且通过验证后,才更新索引。通过权限受限的刷新工作流续签将要过期的元数据,不重新构建/签名二进制文件。并发更新源变更采用比较并交换操作,保持序号单调递增。最终密钥保管、过期/续签间隔和分支规则在实施接入时确定。
首先支持 GitHub 下载。关闭自动重定向;逐跳检查 HTTPS 地址是否属于经过明确验证的 GitHub 发行存储主机,不携带 Cookie、凭据,也不允许协议降级或任意/本地目标。建议初始限制为:元数据 512 KiB、安装包最多 512 MiB、最多五次重定向、更新缓存配额 512 MiB,同时限制时间/并发并执行清单声明的实际字节限制。验收时确认真实存储主机;未知主机安全失败,不扩大白名单。CNB 回退应在相同已签名字节和存储路径验证后加入。唯一部分下载保存在 cache/updates/;安装器标为可用前,验证大小/哈希、已签名元数据和 Authenticode。缓存清理只触及归属明确的更新下载,不碰封面或其余用户数据。
安装版 Manager 经确认更新后,所有实例完成保存、正常退出,由已验证的独立辅助程序调用同一个安装器。传入已验证的安装凭证和事务 ID,不接受任意命令或 URL。便携版 Manager 提供已验证下载及新目录使用指引,不自动写入其解压目录。
发行工作流变更
章节“发行工作流变更”保留日常编译/测试及仅版本标签触发的发行物构建。未签名可安装格式现已明确采用第 2 版结构,共七个附件:Setup、便携 ZIP、双语说明、原始 portable-release.json、外层 release.json 和 SHA256SUMS。外层元数据以 signed=false、installer=true、portable=true 绑定长度/摘要及部署清单。旧第 1 版便携五产物验证器继续严格且独立保留。未来已签名清单必须明确列举类型、摘要及签名策略;未签名夹具不能证明认证产物契约。
D3 生产签名工作流尚未实现。未来获批后的已签名标签发行须加入签名批准、Setup/卸载器检查及干净客户端证据。要求签名的渠道在签名/批准/时间戳验证不可用时必须失败,不允许静默发布未签名文件。明确未签名预览保留为单独标记的路径,不被认证更新器接受。手动触发继续只生成预览产物,不公开发布 Release。
GitHub 与已配置 CNB 上传相同的最终不可变字节。只有已公告产物通过验证后,才发布渠道元数据。CNB 失败时,可以公告 GitHub 可用,不宣称 CNB 完成;镜像验证后才加入。重试复用已签名产物,不产生新签名时间戳。签名批准过期或产物保留期届满时,需要有文档记录的新版本/恢复路径。
实施阶段与完成门槛
章节“实施阶段与完成门槛”| 阶段 | 具体工作 | 进入下一阶段前的门槛 |
|---|---|---|
| D1a:隔离安装器原型 | 固定 Inno;试验 C# 启动器/部署边界;最终布局、双语安装、快捷方式、仅卸载 Manager 及便携迁移 | 可丢弃的干净受支持 Windows、标准账号、离线安装、两种语言、稳定数据路径及保留 Runner;无需准备 SDK/运行时 |
| D1b:安装恢复 | 共享安装锁、完整版本暂存、事务日志/指针、启动器升级、手动修复及归属明确的文件清理 | 真实进程并发、中断各阶段、锁/磁盘/重解析点故障、任务栏身份、恢复,以及无混合版本 DLL |
| D2:公开预览与签名准备 | 明确未签名的技术安装器结构/标签发布;实际依赖/许可证清单、Runner PE 元数据、签名政策/角色/MFA 及 Foundation 申请 | 申请前已有下载核验通过的当前形式未签名技术预发布,随后审核材料并取得服务方实际批准;本机验收不豁免 D1b/稳定版门槛,也不证明已经取得证书 |
| D3:已签名发行 | 两阶段签名集成、已签名卸载器、签后 Runner 清单、产物结构的签名扩展及更新信任根/索引 | 拒绝错误签名者/篡改/时间戳/哈希/版本;检查可下载已签名安装器与 ZIP;已公告镜像一致 |
| D4:仅检查更新 | 双语更新界面/偏好、已签名索引验证、渠道、新鲜度及受限网络/缓存 | 自动检查启用前或关闭后无后台请求;手动检查仅授权本次请求,不开启自动检查;关闭/取消终止对应在途工作。离线/限流/错误行为正确,回滚/冻结/密钥轮换测试;不写应用/游戏文件 |
| D5:确认后安装 | 已验证下载,按需辅助程序调用已验收安装器,多实例保存/退出,兼容 Runner 延后替换 | 端到端升级/修复及干净客户端故障恢复;便携版保持手动;不强杀游戏或覆盖配置 |
| 稳定版资格 | P0–P2 原生/玩家、安装器/签名/发行门槛及支持文档;可选更新与 Steam 写入仅在纳入交付时要求各自验收 | Windows 防护启用下全新下载,以及单独授权的真实 Steam 测试;不扩大游戏/成就承诺 |
签名准备调研期间可以开始 D1 实施。明确未签名的技术预览可以基于限定的本机隔离证据提供 D2 所需当前形式产物,尚无环境的干净客户端及剩余原生/版本保留门槛继续保留;它不是稳定安装器或认证更新渠道。D2 审批时间取决于外部,不承诺日历期限。仅检查更新可以在 D3 前使用测试夹具开发,但公开认证安装要求 D1b 和 D3。自动下载或无人值守启动回滚不阻碍首个可靠安装器交付。
按日期整理的执行队列将阶段拆为可执行任务:原生 UI 验收、干净客户端真实版本升级/恢复、未签名技术安装器、获批签名,再交付可选检查/下载/安装。标签流水线现已生成明确的第 2 版七产物集合,并保留旧便携验证。公开当前形式产物的下载核验是申请前置条件,不证明 Foundation 批准或稳定版资格。正常合并继续只测试/编译,手动运行继续只生成预览。
Manager 部署比较三段数字版本与部署清单摘要。仅改变预发布标签会改变清单、保留数字版本,所以 0.2.1-preview.1 → 0.2.1-preview.2 不是受支持升级。验收使用冻结旧包和真正构建、尚未使用的新基础版本,新签名载荷再用新基础版本;重试保持产物完全不变。版本保留另设门槛:确认健康后保留当前及最近一个已验证可用的旧版本,在独占锁下仅移除清单验证归属的更旧文件,保留未知/隔离恢复数据并限制磁盘使用。
冻结的 0.2.1/0.2.2 部署实现会拒绝安装根目录未知文件和状态 JSON 字段。版本保留所需健康记录或日志布局必须保持真实旧二进制可回滚,不能静默扩展这些格式。现有空间检查和进程停止恢复测试不实现清理或保留版本配额;注册表/快捷方式失败、物理磁盘耗尽与整机断电验收也仍待完成。
验收矩阵
章节“验收矩阵”| 领域 | 必须观察的结果 |
|---|---|
| 干净安装 | 无 SDK 的受支持 Windows 11 x64、普通非管理员用户、离线使用、英语/中文、中文/含空格用户路径、两个 Windows 用户互相隔离 |
| 所有权 | 错误根目录、自定义 Steam/游戏/数据位置、目录联接、未知文件、重复安装/修复及仅卸载 Manager;不删除无关内容 |
| 并发 | 多 Manager、等待/进行中的保存、激活期间新启动、双安装器/辅助程序、锁定启动器及运行中的 Runner/游戏;不强制退出 |
| 中断 | 事务日志/文件/状态/快捷方式/注册表各阶段失败或停止、磁盘满、杀毒软件/文件锁、旧事务日志、启动失败、迟到的健康确认及手动恢复 |
| 签名 | 未签名/错误身份、PE 篡改、缺失/错误时间戳、到期但有时间戳的证书、缓存离线信任及证书链缺失、在线吊销/无法访问响应、签前 Runner 哈希、同版本字节变化及共享发布者的无关安装包 |
| 更新元数据 | 错误签名/密钥轮换、重复键/格式错误 JSON、旧序号、同序号字节变化、清理/卸载后保留信任状态、过期/时钟问题、错误应用/平台/渠道/契约及替换产物 |
| 网络/缓存 | 关闭/离线、超时/429/404、恶意重定向、流式长度超限、部分/损坏下载、取消及配额;保留封面/用户文件 |
| 产品连续性 | 升级/卸载后 Manager 关闭时,稳定 Runner 仍可启动;配置/启动项/存档不变;便携迁移位置及任务栏固定快捷方式保留 |
自动测试使用可丢弃夹具及真实进程行为;干净虚拟机安装测试是独立门槛,不等同于托管 Windows Server 编译或现有开发环境发布测试。真实 Steam 验收仍需要明确范围与授权,记录/恢复所选启动项,验证游戏/存档完整性。不自行选择覆盖存在冲突的存档/云端进度。