dsh-app-updater 1.3.2 → 1.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +293 -191
- package/CONTRACT.md +150 -150
- package/LICENSE +20 -20
- package/README.en.md +243 -239
- package/README.md +275 -253
- package/RELEASING.md +75 -75
- package/cordis.patch.yml +8 -8
- package/icon.svg +32 -32
- package/lib/client.js +1491 -1460
- package/lib/elevate.js +204 -204
- package/lib/engine.js +1315 -1282
- package/lib/index.js +597 -597
- package/lib/macos.js +494 -409
- package/lib/platform.js +199 -199
- package/lib/proc.js +91 -91
- package/lib/registry.js +120 -120
- package/lib/state.js +141 -141
- package/lib/version.js +81 -81
- package/lib/winget.js +337 -337
- package/package.json +68 -68
- package/test/deny.mjs +148 -148
- package/test/harness.mjs +125 -125
- package/test/render.mjs +613 -570
- package/test/unit.mjs +590 -552
package/CONTRACT.md
CHANGED
|
@@ -1,150 +1,150 @@
|
|
|
1
|
-
# dsh-app-updater 契约(宿主 ↔ 客户端)
|
|
2
|
-
|
|
3
|
-
插件 id:`dsh-app-updater` 显示名:应用更新(App Updater)
|
|
4
|
-
|
|
5
|
-
## 文件布局
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
dsh-app-updater/
|
|
9
|
-
├─ package.json # main: ./lib/index.js, exports ./client, dsh.bundle.patch, dsh.client
|
|
10
|
-
├─ cordis.patch.yml # insert 行:id=dsh-app-updater, name=dsh-app-updater
|
|
11
|
-
├─ lib/
|
|
12
|
-
│ ├─ index.js # 宿主半身:cordis 插件,注册 /dsh-app-updater/* 路由
|
|
13
|
-
│ ├─ platform.js # 运行环境识别:Windows / macOS、版本、CPU 架构、引擎选择
|
|
14
|
-
│ ├─ engine.js # 扫描 / 下载 / 安装编排(Windows=winget / macOS=Homebrew)
|
|
15
|
-
│ ├─ winget.js # winget 定位、调用、表格解析
|
|
16
|
-
│ ├─ registry.js # 注册表 Uninstall 键枚举(覆盖 winget 未收录的应用)
|
|
17
|
-
│ ├─ version.js # 版本比较(Windows 风格 1.2.3.4 + 字母后缀)
|
|
18
|
-
│ ├─ state.js # 持久化状态(~/.dsh/dsh-app-updater/state.json)
|
|
19
|
-
│ └─ client.js # 浏览器半身:设置页 UI
|
|
20
|
-
└─ README.md
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## 运行环境与引擎
|
|
24
|
-
|
|
25
|
-
- `platform.js` 输出 `env`:`{ platform, family: windows|macos|other, osName, osVersion, osBuild, arch: arm64|x64|x86, archLabel, wingetArch, cpuModel, cpuCount }`。
|
|
26
|
-
- 引擎:Windows → `winget`;macOS → `homebrew`;其它 → `none`(扫描/更新接口返回 400)。
|
|
27
|
-
- 架构匹配:`settings.matchSystemArch !== false` 时,Windows 侧把 `env.wingetArch` 传给
|
|
28
|
-
`winget download/upgrade --architecture`;清单缺该架构时自动退回自动匹配并写日志。
|
|
29
|
-
macOS 侧由 Homebrew 决定 cask 架构。
|
|
30
|
-
- 提权(`lib/elevate.js`):`settings.autoElevate !== false` 且当前进程没有管理员令牌时,
|
|
31
|
-
安装类命令(安装包本体、`winget upgrade` 兜底)交给 `Start-Process -Verb RunAs` 的提权副本
|
|
32
|
-
执行,退出码与输出写进临时文件后读回;`cancelled` 表示 UAC 被取消(1223)。
|
|
33
|
-
读类命令(`winget list` / `upgrade --include-unknown` / `--version`)不提权。
|
|
34
|
-
- 复核:安装后必须用「安装前版本 / 安装后版本 / 目标版本」判断是否真的生效,退出码 0 不算成功
|
|
35
|
-
(机器级安装包在未提权时会静默退出 0 却什么都没装)。`update.results[].installOk` 记录
|
|
36
|
-
安装器自身是否报成功,`verified` 记录复核时读到的版本。
|
|
37
|
-
- 自带更新服务:Edge 的 winget 目录条目是企业版 MSI,与本机消费版安装技术不匹配
|
|
38
|
-
(`0x8A15008E`),改走 `MicrosoftEdgeUpdate.exe /ua`,再由复核轮询确认版本就位。
|
|
39
|
-
|
|
40
|
-
## 宿主 HTTP 路由
|
|
41
|
-
|
|
42
|
-
全部 `kind: "exact"`,前缀 `/dsh-app-updater/`。每个请求先过 **connection 准入**:
|
|
43
|
-
`ctx.connection.admit(req)`(DSH 的 Host/Origin 信任校验 + 浏览器会话 / API 认证,
|
|
44
|
-
宿主自己的 `/api` 路由用的同一套),被拒即返回 `401`(未认证)/ `403`(不可信来源)/
|
|
45
|
-
`409`(连接被占用),响应头带 `X-DSH-Admission: denied`;写操作再要求 `confirm: true`。
|
|
46
|
-
|
|
47
|
-
**默认拒绝**(1.3.1 起):宿主没有 `connection` 服务时不再「仅凭回环地址放行」,而是 `403`。
|
|
48
|
-
只有用户显式开启兼容模式(插件配置 `allowLegacyLoopback: true` 或环境变量
|
|
49
|
-
`DSH_APP_UPDATER_ALLOW_LEGACY_LOOPBACK=1`)时,回环请求才放行,并带
|
|
50
|
-
`X-DSH-Admission: loopback-legacy-optin` 与 `X-DSH-Admission-Warning`(见 `lib/index.js` 的
|
|
51
|
-
`admissionGate` / `resolveLegacyLoopbackOptIn`)。
|
|
52
|
-
|
|
53
|
-
### GET /dsh-app-updater/state.json
|
|
54
|
-
|
|
55
|
-
```jsonc
|
|
56
|
-
{
|
|
57
|
-
"ok": true,
|
|
58
|
-
"platform": "win32",
|
|
59
|
-
"env": { "platform": "win32", "family": "windows", "osName": "Windows 11", "osVersion": "10.0.26300", "osBuild": "26300", "arch": "x64", "archLabel": "x64(AMD64)", "wingetArch": "x64", "cpuModel": "13th Gen Intel(R) Core(TM) i7-13700K", "cpuCount": 24 },
|
|
60
|
-
"envSummary": "Windows 11(build 26300) · x64(AMD64)",
|
|
61
|
-
"engine": { "id": "winget", "available": true, "version": "1.29.380" },
|
|
62
|
-
"capabilities": { "scan": true, "update": true, "checkVersions": true, "storeAppsIncluded": true, "note": "" },
|
|
63
|
-
"winget": { "available": true, "version": "v1.29.380", "path": "C:\\...\\winget.exe" },
|
|
64
|
-
"phase": "idle", // idle | scanning | updating
|
|
65
|
-
"scan": { "running": false, "startedAt": 0, "finishedAt": 0, "error": null },
|
|
66
|
-
"update": { "running": false, "total": 0, "done": 0, "current": null, "error": null },
|
|
67
|
-
"apps": { "scannedAt": 0, "stats": { "total": 0, "upgradable": 0, "unsupported": 0 }, "items": [], "engine": "winget" },
|
|
68
|
-
"log": [ { "at": 0, "level": "info|warn|error|success", "text": "..." } ],
|
|
69
|
-
"settings": { "includeStoreApps": true, "includeRegistryOnly": true, "downloadDir": "", "keepInstallers": true, "hashFallbackUpgrade": true, "dryRun": false, "matchSystemArch": true, "autoElevate": true },
|
|
70
|
-
// 准入现状,供界面与复核确认当前走哪条路径(默认 "deny" 不会出现在能读到响应的地方)
|
|
71
|
-
"admission": { "mode": "connection|connection+loopback-legacy|loopback-legacy-optin|deny", "service": true, "allowLegacyLoopback": false, "warning": null }
|
|
72
|
-
}
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
`apps.items[]`(单条应用):
|
|
76
|
-
|
|
77
|
-
```jsonc
|
|
78
|
-
{
|
|
79
|
-
"id": "Google.Chrome", // winget id;注册表项 "reg:<key>";macOS 由 Homebrew 管理的是 "brew:<cask token>",其余 "macapp:<bundle id>"
|
|
80
|
-
"name": "Google Chrome",
|
|
81
|
-
"version": "155.0.8059.85", // 已安装版本,未知时 ""
|
|
82
|
-
"available": "156.0.8078.48", // 可升级到的版本,无更新时 ""
|
|
83
|
-
"publisher": "Google LLC",
|
|
84
|
-
"source": "winget", // winget | msstore | registry | homebrew | appstore | app
|
|
85
|
-
"installLocation": "C:\\Program Files\\Google\\Chrome\\Application",
|
|
86
|
-
"hasUpdate": true,
|
|
87
|
-
"updateSupported": true, // 本插件能否驱动更新
|
|
88
|
-
"reason": null, // null | "not-in-catalog" | "not-managed" | "unknown-version" | "pinned" | "store-managed" | "system-component"
|
|
89
|
-
"kind": "exe" // exe | msi | msix | inno | cask | app | null(未知)
|
|
90
|
-
}
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
`reason` 里的 `not-managed` 是 macOS 专用:应用在标准目录里枚举到了,但不是由 Homebrew 管理
|
|
94
|
-
(拖 DMG / 手动安装),所以能列出、不能一键更新。`source` 的 `app` / `appstore` 同理只出现在
|
|
95
|
-
macOS。macOS 的扫描范围是 `/Applications`、`/Applications/Utilities`、`/System/Applications`
|
|
96
|
-
(及其 `Utilities`)与 `~/Applications`;装在别处的应用不在范围内。
|
|
97
|
-
|
|
98
|
-
### POST /dsh-app-updater/scan
|
|
99
|
-
|
|
100
|
-
body `{ "confirm": true, "force": true }` → `{ "ok": true, "started": true }`(异步;结果看 state.json / apps.json)
|
|
101
|
-
|
|
102
|
-
### GET /dsh-app-updater/apps.json
|
|
103
|
-
|
|
104
|
-
`{ "ok": true, "scannedAt": 0, "stats": {...}, "items": [App...], "warnings": ["..."] }`
|
|
105
|
-
|
|
106
|
-
### POST /dsh-app-updater/update
|
|
107
|
-
|
|
108
|
-
body `{ "confirm": true, "ids": ["Google.Chrome", "..."], "mode": "silent" }`
|
|
109
|
-
→ `{ "ok": true, "started": true, "queued": 3 }`
|
|
110
|
-
(串行执行,逐条:下载官网全量包 → 校验哈希 → 静默安装(需要管理员时自动提权)→ 复核版本。
|
|
111
|
-
Edge 由 `MicrosoftEdgeUpdate.exe /ua` 处理。`settings.dryRun` 时只下载、不安装、不复核。)
|
|
112
|
-
|
|
113
|
-
`update.results[]`(每条一次更新):
|
|
114
|
-
|
|
115
|
-
```jsonc
|
|
116
|
-
{
|
|
117
|
-
"id": "Microsoft.Edge",
|
|
118
|
-
"ok": false, // 最终结论:复核不通过就是 false,哪怕安装器报成功
|
|
119
|
-
"installOk": true, // 安装器自身是否报成功(退出码 0 / winget 成功)
|
|
120
|
-
"error": "安装报告成功,但没有生效:版本没有变化(仍为 156.0.4314.50,目标 156.0.4314.58)",
|
|
121
|
-
"installer": "C:\\...\\Microsoft Edge_156.0.4314.58_Machine_X64_msi_en-US.msi",
|
|
122
|
-
"manifest": "C:\\...\\Microsoft Edge_156.0.4314.58_Machine_X64_msi_en-US.yaml",
|
|
123
|
-
"verified": "156.0.4314.50", // 复核时读到的已装版本
|
|
124
|
-
"selfUpdater": "edgeupdate", // 走自带更新服务时存在
|
|
125
|
-
"note": "已交给 Microsoft Edge 更新服务,等待版本就位",
|
|
126
|
-
"durationMs": 33288
|
|
127
|
-
}
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
### POST /dsh-app-updater/cancel
|
|
131
|
-
|
|
132
|
-
→ `{ "ok": true }`(取消尚未开始的项目;提权副本是独立进程,取消只会停掉启动器,已经开始的那次安装会自己跑完)
|
|
133
|
-
|
|
134
|
-
### POST /dsh-app-updater/settings
|
|
135
|
-
|
|
136
|
-
body `{ "confirm": true, "settings": { ... } }` → `{ "ok": true, "settings": {...} }`
|
|
137
|
-
|
|
138
|
-
### POST /dsh-app-updater/open-downloads
|
|
139
|
-
|
|
140
|
-
→ `{ "ok": true, "path": "..." }`(在资源管理器中打开下载目录)
|
|
141
|
-
|
|
142
|
-
## 客户端要求
|
|
143
|
-
|
|
144
|
-
- `window.__ModuleLoader__.load({ id: "dsh-app-updater", factory: (require) => { ... } })`
|
|
145
|
-
- `exports.inject = ["slots", "locale"]`
|
|
146
|
-
- 注册 `settings.section`:`{ name: "settings.section", id: "dsh-app-updater", order: 42, label: () => "应用更新" }`
|
|
147
|
-
- 只用 `require("react")`;不引入其它运行时依赖
|
|
148
|
-
- 页面:顶部工具条(刷新检测 / 全部更新 / 取消 / 打开下载目录)+ 统计条 + 可筛选可多选的表格 + 底部日志
|
|
149
|
-
- 表格列:勾选 / 应用名 / 已装版本 / 可升级到 / 来源 / 状态 / 操作
|
|
150
|
-
- 所有请求带 `cache: "no-store"`;轮询 state.json(扫描/更新中 800ms,空闲 4s)
|
|
1
|
+
# dsh-app-updater 契约(宿主 ↔ 客户端)
|
|
2
|
+
|
|
3
|
+
插件 id:`dsh-app-updater` 显示名:应用更新(App Updater)
|
|
4
|
+
|
|
5
|
+
## 文件布局
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
dsh-app-updater/
|
|
9
|
+
├─ package.json # main: ./lib/index.js, exports ./client, dsh.bundle.patch, dsh.client
|
|
10
|
+
├─ cordis.patch.yml # insert 行:id=dsh-app-updater, name=dsh-app-updater
|
|
11
|
+
├─ lib/
|
|
12
|
+
│ ├─ index.js # 宿主半身:cordis 插件,注册 /dsh-app-updater/* 路由
|
|
13
|
+
│ ├─ platform.js # 运行环境识别:Windows / macOS、版本、CPU 架构、引擎选择
|
|
14
|
+
│ ├─ engine.js # 扫描 / 下载 / 安装编排(Windows=winget / macOS=Homebrew)
|
|
15
|
+
│ ├─ winget.js # winget 定位、调用、表格解析
|
|
16
|
+
│ ├─ registry.js # 注册表 Uninstall 键枚举(覆盖 winget 未收录的应用)
|
|
17
|
+
│ ├─ version.js # 版本比较(Windows 风格 1.2.3.4 + 字母后缀)
|
|
18
|
+
│ ├─ state.js # 持久化状态(~/.dsh/dsh-app-updater/state.json)
|
|
19
|
+
│ └─ client.js # 浏览器半身:设置页 UI
|
|
20
|
+
└─ README.md
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 运行环境与引擎
|
|
24
|
+
|
|
25
|
+
- `platform.js` 输出 `env`:`{ platform, family: windows|macos|other, osName, osVersion, osBuild, arch: arm64|x64|x86, archLabel, wingetArch, cpuModel, cpuCount }`。
|
|
26
|
+
- 引擎:Windows → `winget`;macOS → `homebrew`;其它 → `none`(扫描/更新接口返回 400)。
|
|
27
|
+
- 架构匹配:`settings.matchSystemArch !== false` 时,Windows 侧把 `env.wingetArch` 传给
|
|
28
|
+
`winget download/upgrade --architecture`;清单缺该架构时自动退回自动匹配并写日志。
|
|
29
|
+
macOS 侧由 Homebrew 决定 cask 架构。
|
|
30
|
+
- 提权(`lib/elevate.js`):`settings.autoElevate !== false` 且当前进程没有管理员令牌时,
|
|
31
|
+
安装类命令(安装包本体、`winget upgrade` 兜底)交给 `Start-Process -Verb RunAs` 的提权副本
|
|
32
|
+
执行,退出码与输出写进临时文件后读回;`cancelled` 表示 UAC 被取消(1223)。
|
|
33
|
+
读类命令(`winget list` / `upgrade --include-unknown` / `--version`)不提权。
|
|
34
|
+
- 复核:安装后必须用「安装前版本 / 安装后版本 / 目标版本」判断是否真的生效,退出码 0 不算成功
|
|
35
|
+
(机器级安装包在未提权时会静默退出 0 却什么都没装)。`update.results[].installOk` 记录
|
|
36
|
+
安装器自身是否报成功,`verified` 记录复核时读到的版本。
|
|
37
|
+
- 自带更新服务:Edge 的 winget 目录条目是企业版 MSI,与本机消费版安装技术不匹配
|
|
38
|
+
(`0x8A15008E`),改走 `MicrosoftEdgeUpdate.exe /ua`,再由复核轮询确认版本就位。
|
|
39
|
+
|
|
40
|
+
## 宿主 HTTP 路由
|
|
41
|
+
|
|
42
|
+
全部 `kind: "exact"`,前缀 `/dsh-app-updater/`。每个请求先过 **connection 准入**:
|
|
43
|
+
`ctx.connection.admit(req)`(DSH 的 Host/Origin 信任校验 + 浏览器会话 / API 认证,
|
|
44
|
+
宿主自己的 `/api` 路由用的同一套),被拒即返回 `401`(未认证)/ `403`(不可信来源)/
|
|
45
|
+
`409`(连接被占用),响应头带 `X-DSH-Admission: denied`;写操作再要求 `confirm: true`。
|
|
46
|
+
|
|
47
|
+
**默认拒绝**(1.3.1 起):宿主没有 `connection` 服务时不再「仅凭回环地址放行」,而是 `403`。
|
|
48
|
+
只有用户显式开启兼容模式(插件配置 `allowLegacyLoopback: true` 或环境变量
|
|
49
|
+
`DSH_APP_UPDATER_ALLOW_LEGACY_LOOPBACK=1`)时,回环请求才放行,并带
|
|
50
|
+
`X-DSH-Admission: loopback-legacy-optin` 与 `X-DSH-Admission-Warning`(见 `lib/index.js` 的
|
|
51
|
+
`admissionGate` / `resolveLegacyLoopbackOptIn`)。
|
|
52
|
+
|
|
53
|
+
### GET /dsh-app-updater/state.json
|
|
54
|
+
|
|
55
|
+
```jsonc
|
|
56
|
+
{
|
|
57
|
+
"ok": true,
|
|
58
|
+
"platform": "win32",
|
|
59
|
+
"env": { "platform": "win32", "family": "windows", "osName": "Windows 11", "osVersion": "10.0.26300", "osBuild": "26300", "arch": "x64", "archLabel": "x64(AMD64)", "wingetArch": "x64", "cpuModel": "13th Gen Intel(R) Core(TM) i7-13700K", "cpuCount": 24 },
|
|
60
|
+
"envSummary": "Windows 11(build 26300) · x64(AMD64)",
|
|
61
|
+
"engine": { "id": "winget", "available": true, "version": "1.29.380" },
|
|
62
|
+
"capabilities": { "scan": true, "update": true, "checkVersions": true, "storeAppsIncluded": true, "note": "" },
|
|
63
|
+
"winget": { "available": true, "version": "v1.29.380", "path": "C:\\...\\winget.exe" },
|
|
64
|
+
"phase": "idle", // idle | scanning | updating
|
|
65
|
+
"scan": { "running": false, "startedAt": 0, "finishedAt": 0, "error": null },
|
|
66
|
+
"update": { "running": false, "total": 0, "done": 0, "current": null, "error": null },
|
|
67
|
+
"apps": { "scannedAt": 0, "stats": { "total": 0, "upgradable": 0, "unsupported": 0 }, "items": [], "engine": "winget" },
|
|
68
|
+
"log": [ { "at": 0, "level": "info|warn|error|success", "text": "..." } ],
|
|
69
|
+
"settings": { "includeStoreApps": true, "includeRegistryOnly": true, "downloadDir": "", "keepInstallers": true, "hashFallbackUpgrade": true, "dryRun": false, "matchSystemArch": true, "autoElevate": true },
|
|
70
|
+
// 准入现状,供界面与复核确认当前走哪条路径(默认 "deny" 不会出现在能读到响应的地方)
|
|
71
|
+
"admission": { "mode": "connection|connection+loopback-legacy|loopback-legacy-optin|deny", "service": true, "allowLegacyLoopback": false, "warning": null }
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`apps.items[]`(单条应用):
|
|
76
|
+
|
|
77
|
+
```jsonc
|
|
78
|
+
{
|
|
79
|
+
"id": "Google.Chrome", // winget id;注册表项 "reg:<key>";macOS 由 Homebrew 管理的是 "brew:<cask token>",其余 "macapp:<bundle id>"
|
|
80
|
+
"name": "Google Chrome",
|
|
81
|
+
"version": "155.0.8059.85", // 已安装版本,未知时 ""
|
|
82
|
+
"available": "156.0.8078.48", // 可升级到的版本,无更新时 ""
|
|
83
|
+
"publisher": "Google LLC",
|
|
84
|
+
"source": "winget", // winget | msstore | registry | homebrew | appstore | app
|
|
85
|
+
"installLocation": "C:\\Program Files\\Google\\Chrome\\Application",
|
|
86
|
+
"hasUpdate": true,
|
|
87
|
+
"updateSupported": true, // 本插件能否驱动更新
|
|
88
|
+
"reason": null, // null | "not-in-catalog" | "not-managed" | "unknown-version" | "pinned" | "store-managed" | "system-component"
|
|
89
|
+
"kind": "exe" // exe | msi | msix | inno | cask | app | null(未知)
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`reason` 里的 `not-managed` 是 macOS 专用:应用在标准目录里枚举到了,但不是由 Homebrew 管理
|
|
94
|
+
(拖 DMG / 手动安装),所以能列出、不能一键更新。`source` 的 `app` / `appstore` 同理只出现在
|
|
95
|
+
macOS。macOS 的扫描范围是 `/Applications`、`/Applications/Utilities`、`/System/Applications`
|
|
96
|
+
(及其 `Utilities`)与 `~/Applications`;装在别处的应用不在范围内。
|
|
97
|
+
|
|
98
|
+
### POST /dsh-app-updater/scan
|
|
99
|
+
|
|
100
|
+
body `{ "confirm": true, "force": true }` → `{ "ok": true, "started": true }`(异步;结果看 state.json / apps.json)
|
|
101
|
+
|
|
102
|
+
### GET /dsh-app-updater/apps.json
|
|
103
|
+
|
|
104
|
+
`{ "ok": true, "scannedAt": 0, "stats": {...}, "items": [App...], "warnings": ["..."] }`
|
|
105
|
+
|
|
106
|
+
### POST /dsh-app-updater/update
|
|
107
|
+
|
|
108
|
+
body `{ "confirm": true, "ids": ["Google.Chrome", "..."], "mode": "silent" }`
|
|
109
|
+
→ `{ "ok": true, "started": true, "queued": 3 }`
|
|
110
|
+
(串行执行,逐条:下载官网全量包 → 校验哈希 → 静默安装(需要管理员时自动提权)→ 复核版本。
|
|
111
|
+
Edge 由 `MicrosoftEdgeUpdate.exe /ua` 处理。`settings.dryRun` 时只下载、不安装、不复核。)
|
|
112
|
+
|
|
113
|
+
`update.results[]`(每条一次更新):
|
|
114
|
+
|
|
115
|
+
```jsonc
|
|
116
|
+
{
|
|
117
|
+
"id": "Microsoft.Edge",
|
|
118
|
+
"ok": false, // 最终结论:复核不通过就是 false,哪怕安装器报成功
|
|
119
|
+
"installOk": true, // 安装器自身是否报成功(退出码 0 / winget 成功)
|
|
120
|
+
"error": "安装报告成功,但没有生效:版本没有变化(仍为 156.0.4314.50,目标 156.0.4314.58)",
|
|
121
|
+
"installer": "C:\\...\\Microsoft Edge_156.0.4314.58_Machine_X64_msi_en-US.msi",
|
|
122
|
+
"manifest": "C:\\...\\Microsoft Edge_156.0.4314.58_Machine_X64_msi_en-US.yaml",
|
|
123
|
+
"verified": "156.0.4314.50", // 复核时读到的已装版本
|
|
124
|
+
"selfUpdater": "edgeupdate", // 走自带更新服务时存在
|
|
125
|
+
"note": "已交给 Microsoft Edge 更新服务,等待版本就位",
|
|
126
|
+
"durationMs": 33288
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### POST /dsh-app-updater/cancel
|
|
131
|
+
|
|
132
|
+
→ `{ "ok": true }`(取消尚未开始的项目;提权副本是独立进程,取消只会停掉启动器,已经开始的那次安装会自己跑完)
|
|
133
|
+
|
|
134
|
+
### POST /dsh-app-updater/settings
|
|
135
|
+
|
|
136
|
+
body `{ "confirm": true, "settings": { ... } }` → `{ "ok": true, "settings": {...} }`
|
|
137
|
+
|
|
138
|
+
### POST /dsh-app-updater/open-downloads
|
|
139
|
+
|
|
140
|
+
→ `{ "ok": true, "path": "..." }`(在资源管理器中打开下载目录)
|
|
141
|
+
|
|
142
|
+
## 客户端要求
|
|
143
|
+
|
|
144
|
+
- `window.__ModuleLoader__.load({ id: "dsh-app-updater", factory: (require) => { ... } })`
|
|
145
|
+
- `exports.inject = ["slots", "locale"]`
|
|
146
|
+
- 注册 `settings.section`:`{ name: "settings.section", id: "dsh-app-updater", order: 42, label: () => "应用更新" }`
|
|
147
|
+
- 只用 `require("react")`;不引入其它运行时依赖
|
|
148
|
+
- 页面:顶部工具条(刷新检测 / 全部更新 / 取消 / 打开下载目录)+ 统计条 + 可筛选可多选的表格 + 底部日志
|
|
149
|
+
- 表格列:勾选 / 应用名 / 已装版本 / 可升级到 / 来源 / 状态 / 操作
|
|
150
|
+
- 所有请求带 `cache: "no-store"`;轮询 state.json(扫描/更新中 800ms,空闲 4s)
|
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 19952730389
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 19952730389
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
SOFTWARE.
|