- feature-roadmap.md: 现有能力盘点 + P1/P2/P3方向 + 竞品参考 - AI深度视差: 远程推理方案(服务端Depth-Anything + 客户端WebGL) - 自动升级模块文档: 设计规格/任务规划/决策记录 - 9份需求契约: 视频/颜色提取/时间段/番茄钟/播放列表/电池/网页/便签/监控
7.4 KiB
7.4 KiB
自动升级系统 — 实现规格
来源:需求探索会话 2026-05-28 状态:待开发
1. 架构总览
┌──────────────┐
│ 远程版本 JSON │ ← 静态文件,放 CDN / OSS
│ version.json │
└──────┬───────┘
│ HTTP GET
▼
┌──────────────────┐
│ u-desktop.exe │ ← 主程序
│ · 启动时检查版本 │
│ · 弹窗提示升级 │
│ · 释放 updater │
└──────┬───────────┘
│ 启动进程
▼
┌──────────────────┐
│ updater.exe │ ← 通用升级器,参数化驱动
│ · 下载安装包 │
│ · SHA256 校验 │
│ · 备份旧版本 │
│ · 替换 + 启动 │
│ · 失败自动回滚 │
└──────────────────┘
2. 主程序改动
2.1 版本号注入
main.go 增加版本变量,编译时注入:
var version = "dev" // -ldflags "-X main.version=0.6.0"
build 脚本 / publish 技能同步更新 ldflags。
2.2 版本检查模块
新增 updater.go:
func checkUpdate() (*UpdateInfo, error)
- 启动时异步调用(不阻塞主流程)
- 请求远程
version.json - 对比当前 version,返回更新信息或 nil
远程 version.json 格式:
{
"version": "0.7.0",
"force": false,
"release_notes": "· 新增视频壁纸\n· 修复全屏检测偶发失效",
"package": {
"url": "https://c.1216.top/u-desktop/u-desktop-0.7.0.zip",
"size": 8388608,
"sha256": "abc123def456..."
}
}
version.json URL 存入 config 或硬编码默认值。
2.3 升级弹窗
用 WebView2 新建一个无边框小窗口,HTML 渲染弹窗内容。
弹窗策略
| force 字段 | 位置 | 按钮 |
|---|---|---|
false |
右下角,托盘图标上方 | [稍后] [立即升级] |
true |
屏幕居中 | [立即升级](仅一个按钮) |
弹窗 HTML 结构
右下角气泡(非强制):
┌─────────────────────────────┐
│ 发现新版本 v0.7.0 │
│ │
│ · 新增视频壁纸 │
│ · 修复全屏检测偶发失效 │
│ │
│ [稍后] [立即升级] │
└─────────────────────────────┘
居中弹窗(强制):
┌─────────────────────────────────────┐
│ │
│ 发现新版本 v0.7.0 │
│ │
│ · 新增视频壁纸 │
│ · 修复全屏检测偶发失效 │
│ │
│ 大小: 8MB | 预计用时: ~10秒 │
│ │
│ [立即升级] │
└─────────────────────────────────────┘
弹窗窗口参数
| 参数 | 右下角 | 居中 |
|---|---|---|
| 宽度 | 340px | 420px |
| 高度 | auto(内容自适应) | auto |
| 位置 | 屏幕右下角 - 边距 20px | 屏幕居中 |
| 样式 | 无边框,圆角,毛玻璃 | 无边框,圆角,毛玻璃 |
| 置顶 | TOPMOST | TOPMOST |
2.4 用户点击"立即升级"
- 从自身嵌入资源释放
updater.exe到临时目录(或主程序同级目录) - 构造命令行参数启动 updater.exe
- 主程序退出
exec.Command(tmpUpdaterPath,
"--package-url", info.Package.URL,
"--sha256", info.Package.SHA256,
"--target", selfExePath,
"--version", info.Version,
"--force", strconv.FormatBool(info.Force),
).Start()
// 主程序退出
2.5 托盘菜单
新增菜单项:"检查更新",手动触发版本检查。
3. updater.exe
3.1 职责
通用升级器,不含业务逻辑,纯参数驱动。可复用于其他产品(u-tabs 等)。
3.2 命令行参数
updater.exe \
--package-url <下载地址> \
--sha256 <SHA256校验值> \
--target <目标exe路径> \
--version <目标版本号> \
--force \
--backup-dir <备份目录,默认 target 同级 backup/>
3.3 流程
1. 显示进度窗口(WebView2 或控制台)
2. HTTP GET 下载 package-url → 临时文件
- 显示下载进度(已下载/总大小)
- 支持断点续传(可选,初期不做)
3. 计算下载文件 SHA256,与参数比对
- 不匹配 → 报错退出
4. 备份当前 target → backup-dir/old-{timestamp}.exe
5. 如果是 zip 包:解压后替换
如果是 exe:直接覆盖
6. 启动新版本 target
7. updater 退出
异常处理:
- 下载失败 → 重试 3 次,间隔 5s
- 校验失败 → 报错,不替换
- 启动新版本后监听 5s,新进程退出则回滚
- 回滚:将 backup 中的旧 exe 还原
3.4 进度显示
初期:无 UI,日志写 updater.log(-H windowsgui 隐藏控制台)。
后续:可加 WebView2 进度窗口。
3.5 日志
写入 updater.log(与 target 同目录),包含时间戳、步骤、错误信息。
4. 构建 & 发布流程
4.1 主程序构建
go build -ldflags "-H windowsgui -X main.version=0.7.0" -o u-desktop.exe
4.2 updater 构建
独立 main 包,单独目录(如 updater/):
cd updater && go build -ldflags "-H windowsgui" -o updater.exe
4.3 发布
- 构建
u-desktop.exe+updater.exe - UPX 压缩(可选)
- 计算 SHA256
- 上传到
c.1216.top - 更新远程
version.json - 更新 publish 技能(自动生成 version.json + 上传)
5. 配置
config.go 新增字段:
type Config struct {
// ... 现有字段
UpdateURL string `json:"update_url"` // 版本检查 URL,默认 https://c.1216.top/u-desktop/version.json
AutoCheckUpdate bool `json:"auto_check_update"` // 启动时自动检查,默认 true
SkipVersion string `json:"skip_version"` // 用户跳过的版本号
}
6. 目录结构
u-desktop/
├── main.go # 增加版本变量
├── updater.go # 新增:版本检查 + 弹窗逻辑
├── config.go # 增加 update 相关字段
├── systray.go # 托盘菜单增加"检查更新"
├── web/
│ ├── update.html # 新增:升级弹窗 HTML
│ └── ...
├── updater/ # 新增:升级器独立目录
│ └── main.go
├── docs/
│ ├── feature-roadmap.md
│ └── auto-update-spec.md # 本文档
└── ...
7. 实施顺序
| 步骤 | 内容 | 依赖 |
|---|---|---|
| 1 | main.go 加版本变量,构建脚本加 ldflags |
无 |
| 2 | updater.go 版本检查函数 + config 字段 |
步骤 1 |
| 3 | 远程 version.json 手动创建 + 上传 |
步骤 2 |
| 4 | 升级弹窗 update.html + Go 端窗口创建 |
步骤 2 |
| 5 | 主程序释放 + 启动 updater.exe | 步骤 4 |
| 6 | updater/ 目录,下载 + 校验 + 替换 + 回滚 |
步骤 5 |
| 7 | 托盘菜单"检查更新" | 步骤 2 |
| 8 | publish 技能集成 version.json 生成 | 步骤 3 |