@@ -31,10 +31,11 @@ sidebar_label: Core 执行流程
31318 . [ Chain→Full 回退机制] ( #8-chainfull-回退机制 )
32329 . [ IPC 通信协议] ( #9-ipc-通信协议 )
333310 . [ UpdateStrategy:Upgrade 进程的执行流程] ( #10-updatestrategyupgrade-进程的执行流程 )
34- 11 . [ Silent Mode:延迟升级机制] ( #11-silent-mode延迟升级机制 )
35- 12 . [ OS 策略的平台差异] ( #12-os-策略的平台差异 )
36- 13 . [ 错误恢复全景] ( #13-错误恢复全景 )
37- 14 . [ 关键代码路径索引] ( #14-关键代码路径索引 )
34+ 11 . [ OSS 模式:对象存储更新执行流程] ( #11-oss-模式对象存储更新执行流程 )
35+ 12 . [ Silent Mode:延迟升级机制] ( #12-silent-mode延迟升级机制 )
36+ 13 . [ OS 策略的平台差异] ( #13-os-策略的平台差异 )
37+ 14 . [ 错误恢复全景] ( #14-错误恢复全景 )
38+ 15 . [ 关键代码路径索引] ( #15-关键代码路径索引 )
3839
3940---
4041
@@ -100,6 +101,8 @@ GeneralUpdate.Core 采用**三层调度 + 两层引擎**的设计:
100101| ------| ---------| ---------------| ------|
101102| 主程序(如 ` MyApp.exe ` ) | ` Client ` | ` ClientStrategy ` | 服务端版本校验、一次性下载所有包、原地升级自身(Upgrade 包)、写 IPC 文件、拉起 Upgrade 进程、退出 |
102103| 升级程序(如 ` Updater.exe ` ) | ` Upgrade ` | ` UpdateStrategy ` | 读 IPC 文件获取版本信息、运行管道升级主程序文件、写回 manifest、拉起主程序、退出 |
104+ | 主程序(OSS 模式) | ` OssClient ` | ` OssStrategy ` | 下载 ` versions.json ` 、SemVer 对比、拉起升级程序、退出(无 IPC) |
105+ | 升级程序(OSS 模式) | ` OssUpgrade ` | ` OssStrategy ` | 读 ` versions.json ` 、下载并解压更新包、写回 manifest、拉起主程序、退出(无 IPC) |
103106
104107---
105108
@@ -1224,11 +1227,106 @@ Upgrade 进程
12241227
12251228---
12261229
1227- ## 11. Silent Mode:延迟升级机制
1230+ ## 11. OSS 模式:对象存储更新执行流程
1231+
1232+ ` OssStrategy ` 是 OSS(Object Storage Service,对象存储服务)模式的核心策略,适用于** 没有后端服务** 的部署场景:版本配置与更新包直接托管在对象存储(阿里云 OSS / AWS S3 / MinIO 等)上,客户端通过静态 ` versions.json ` 文件完成版本检查与更新。
1233+
1234+ 与标准模式不同,OSS 模式** 不写 IPC 文件、不请求 Verification / Report API** 。Client 与 Upgrade 之间通过安装目录下的 ` versions.json ` 文件传递更新上下文,因此 ` OssClient ` 与 ` OssUpgrade ` 必须使用一致的 ` MainAppName ` / ` UpdateAppName ` 配置。
1235+
1236+ ### 11.1 完整流程
1237+
1238+ ``` mermaid
1239+ flowchart TB
1240+ subgraph OSS_CLIENT["OssClient 主程序"]
1241+ direction TB
1242+ START(["启动"]) --> OC1["下载 versions.json\nUpdateUrl → {MainAppName}_versions.json"]
1243+ OC1 --> OC2["反序列化版本列表\n按 PubTime 倒序取最新版本"]
1244+ OC2 --> OC3{"SemVer 对比\n最新版本大于 ClientVersion?"}
1245+ OC3 -- "否" --> OC_EXIT["返回\n无需更新"]
1246+ OC3 -- "是" --> OC4["解析升级程序路径\n优先 UpdatePath → InstallPath"]
1247+ OC4 --> OC5["Process.Start(升级程序)"]
1248+ OC5 --> OC6["GracefulExit\n主程序退出"]
1249+ end
1250+
1251+ subgraph OSS_UPGRADE["OssUpgrade 升级程序"]
1252+ direction TB
1253+ US1(["启动"]) --> US2["读取 versions.json\n或自定义 DownloadSource"]
1254+ US2 --> US3["筛选 Version 大于 ClientVersion\n按 PubTime 升序 → DownloadAsset"]
1255+ US3 --> US4["计算 LastVersion\nSemVer 最大值"]
1256+ US4 --> US5["OnBeforeUpdateAsync 钩子"]
1257+ US5 --> US6{"返回 false?"}
1258+ US6 -- "是" --> US_EXIT["取消更新"]
1259+ US6 -- "否" --> US7["下载所有更新包\nDefaultDownloadOrchestrator"]
1260+ US7 --> US8["解压 zip → 安装目录\n删除压缩包"]
1261+ US8 --> US9["写回 manifest\nClientVersion = LastVersion"]
1262+ US9 --> US10["OnDownloadCompleted / OnAfterUpdate 钩子"]
1263+ US10 --> US11["OnBeforeStartApp 钩子"]
1264+ US11 --> US12["StartAppAsync\n拉起主程序"]
1265+ US12 --> US13["GracefulExit\n升级程序退出"]
1266+ end
1267+
1268+ OC5 -. "共享 versions.json(无 IPC)" .-> US1
1269+ ```
1270+
1271+ ### 11.2 与标准模式的关键差异
1272+
1273+ | 维度 | 标准 Client / Upgrade | OSS 模式 |
1274+ | ------| ----------------------| ----------|
1275+ | 服务端 API | 需要 Verification / Report API | 不需要,纯静态文件 |
1276+ | 进程间通信 | 加密 IPC 文件 | 安装目录下的 ` versions.json ` 文件 |
1277+ | 包类型 | Chain(差分)+ Full(全量) | 仅 Full(zip 全量包) |
1278+ | 更新管道 | Hash → Compress → Patch | Hash 校验 + 解压(无差分 Patch) |
1279+ | 备份 / 回滚 | 有(` .backups/ ` ) | 无 |
1280+ | 黑名单机制 | 有(CheckFail) | 无 |
1281+ | 版本对比 | 服务端返回 Assets 列表 | 本地解析 versions.json + SemVer 对比 |
1282+ | 防止更新循环 | ` AllPackagesSucceeded ` 闸门 | 更新成功后回写 manifest 的 ` ClientVersion ` |
1283+
1284+ ### 11.3 OssClient:版本检查与拉起升级
1285+
1286+ 【说明】` OssClient ` 只负责"检查 + 拉起",** 不下载更新包** 。版本配置下载失败或文件不存在时直接返回,不抛异常、不阻塞主程序启动。
1287+
1288+ | 步骤 | 行为 | 关键实现 |
1289+ | ------| ------| ----------|
1290+ | 1 | 下载版本配置 | ` UpdateUrl ` → 保存为 ` {MainAppName}_versions.json ` (InstallPath 下) |
1291+ | 2 | 解析并取最新 | ` JsonContext.OssVersionRecordJsonContext ` 反序列化,按 ` PubTime ` 倒序 |
1292+ | 3 | 版本对比 | SemVer 2.0:` latest.Version > ClientVersion ` 才继续 |
1293+ | 4 | 解析升级程序路径 | 优先 ` UpdatePath ` ,回退 ` InstallPath ` ;` UpdateAppName ` 默认 ` Update.exe ` |
1294+ | 5 | 拉起升级程序 | ` Process.Start(appPath) ` ,** 不传任何参数** ;升级程序靠自身代码的 ` AppType.OssUpgrade ` 和 manifest 身份执行升级 |
1295+ | 6 | 退出主程序 | ` GracefulExit.CurrentProcessAsync() ` |
1296+
1297+ ### 11.4 OssUpgrade:下载、解压与应用
1298+
1299+ 【说明】` OssUpgrade ` 完成实际的下载与安装,全程不依赖服务端。
1300+
1301+ | 步骤 | 行为 | 关键实现 |
1302+ | ------| ------| ----------|
1303+ | 1 | 读取版本配置 | ` {MainAppName}_versions.json ` (Client 已下载)或自定义 ` DownloadSource ` |
1304+ | 2 | 筛选更新包 | 过滤 ` Version > ClientVersion ` ,按 ` PubTime ` 升序转为 ` DownloadAsset ` (` SHA256 = Hash ` ) |
1305+ | 3 | 计算目标版本 | 所有可解析版本号的 SemVer 最大值 → ` LastVersion ` |
1306+ | 4 | 前置钩子 | ` OnBeforeUpdateAsync ` ,返回 false 可取消更新 |
1307+ | 5 | 下载更新包 | 默认 ` DefaultDownloadOrchestrator ` (超时默认 60s),或自定义 ` DownloadOrchestrator ` |
1308+ | 6 | 解压安装 | ` Format.Zip ` 解压到 InstallPath,完成后删除压缩包 |
1309+ | 7 | 回写版本 | ` ManifestInfo.TryUpdateVersion ` 更新 manifest 的 ` ClientVersion ` ,防止无限更新循环 |
1310+ | 8 | 收尾钩子 | ` OnDownloadCompleted ` → ` OnAfterUpdate ` → ` OnBeforeStartApp ` |
1311+ | 9 | 拉起主程序 | ` StartAppAsync() ` |
1312+ | 10 | 退出 | ` GracefulExit.CurrentProcessAsync() ` ;异常时触发 ` OnUpdateErrorAsync ` + 上报 UpdateFailed |
1313+
1314+ ### 11.5 注意事项
1315+
1316+ - OSS 模式** 没有备份 / 回滚机制** ,更新包解压后直接覆盖安装目录,建议发布前充分测试
1317+ - OSS 模式** 不区分主程序与升级程序的更新包** :` versions.json ` 中所有高于当前版本的包都会被依次下载并应用
1318+ - 打包更新包时请勿包含组件内部依赖程序集(如 ` System.Text.Json.dll ` 、` Microsoft.Bcl.AsyncInterfaces.dll ` 等)
1319+ - 版本号必须使用 SemVer 2.0 格式(如 ` 1.0.0.0 ` ),否则版本对比会静默失败
1320+ - Bucket 建议设为私有并使用预签名 URL;` OssDownloadSource ` 原生支持预签名 URL 场景
1321+ - 与标准模式一致,OSS 模式同样支持 ` Hooks<T>() ` 生命周期钩子、` UpdateReporter<T>() ` 状态上报、` DownloadSource<T>() ` / ` DownloadOrchestrator<T>() ` 自定义下载来源与编排
1322+
1323+ ---
1324+
1325+ ## 12. Silent Mode:延迟升级机制
12281326
12291327Silent Mode 是标准更新流程的一种变体,唯一的区别是** 启动升级进程的时机从"立即"变成了"进程退出时"** 。
12301328
1231- ### 11 .1 标准模式 vs 静默模式
1329+ ### 12 .1 标准模式 vs 静默模式
12321330
12331331```
12341332标准模式:
@@ -1250,7 +1348,7 @@ AppDomain.ProcessExit (进程退出时):
12501348 → Upgrade 进程启动 → 应用更新 → 下次启动时版本已更新
12511349```
12521350
1253- ### 11 .2 完整流程图
1351+ ### 12 .2 完整流程图
12541352
12551353``` mermaid
12561354flowchart TB
@@ -1292,7 +1390,7 @@ flowchart TB
12921390 end
12931391```
12941392
1295- ### 11 .3 TryLaunchUpgrade — 兜底方法
1393+ ### 12 .3 TryLaunchUpgrade — 兜底方法
12961394
12971395``` csharp
12981396// SilentPollOrchestrator.cs:187-210
@@ -1310,7 +1408,7 @@ public bool TryLaunchUpgrade()
13101408
13111409---
13121410
1313- ## 12 . OS 策略的平台差异
1411+ ## 13 . OS 策略的平台差异
13141412
13151413| 方面 | Windows | Linux | macOS |
13161414| ------| ---------| -------| -------|
@@ -1323,7 +1421,7 @@ Bowl 是一个 Windows-only 的崩溃守护进程。当主程序意外退出时
13231421
13241422---
13251423
1326- ## 13 . 错误恢复全景
1424+ ## 14 . 错误恢复全景
13271425
13281426| 错误场景 | 捕获位置 | 处理方式 | 后果 |
13291427| ----------| ----------| ----------| ------|
@@ -1357,7 +1455,7 @@ private void TryRollback()
13571455
13581456---
13591457
1360- ## 14 . 关键代码路径索引
1458+ ## 15 . 关键代码路径索引
13611459
13621460| 步骤 | 文件 | 关键行 |
13631461| ------| ------| --------|
0 commit comments