Initial import of WPF migration tool

This commit is contained in:
chen qiang
2026-08-25 16:23:14 +08:00
commit 227f92c45b
47 changed files with 5204 additions and 0 deletions
+99
View File
@@ -0,0 +1,99 @@
# Velopack 迁移总结
## 目标
将自动更新从 AutoUpdater.NET 迁移到 Velopack,解决 .NET 8 ZipExtractor 依赖问题。
## 根本原因
AutoUpdater.NET 1.9.0 内部嵌入了 ZipExtractor.exe(.NET 8 WinForms 程序),用户机器只有 .NET 10 时无法运行。
## 修改文件
### 1. `henlo_migration_wpf10.csproj`
- 移除: `Autoupdater.NET.Official` 1.9.0
- 添加: `Velopack` 0.0.1298
### 2. `App.xaml.cs`
- 移除所有 AutoUpdater 相关代码
- 添加 Velopack 初始化: `VelopackApp.Build().Run()`
- 添加 `UpdateManager` 用于检查/下载/应用更新
- 后台静默检查更新
- 手动检查更新支持弹窗确认
### 3. `Views/HomeWindow.xaml.cs`
- `CheckUpdate_Click` 改为 async void,调用 `CheckUpdateManualAsync`
### 4. `pack.bat` (新增)
Velopack 打包脚本,用法:
```batch
pack.bat 1.0.002
```
## Velopack 工作流程
```
开发机:
dotnet publish → vpk pack → releases/
├── setup.exe (安装程序)
├── update.nupkg (更新包)
└── RELEASES (更新索引)
服务器:
上传 releases/ 到 http://zjhenlo.henlo.net:8878/henlo_migration/auto_update/
客户端:
启动 → VelopackApp.Build().Run()
→ UpdateManager.CheckForUpdatesAsync()
→ 有新版本 → DownloadUpdatesAsync()
→ 提示用户重启 → ApplyUpdatesAndRestart()
```
## 关键 API
```csharp
// 初始化(必须在启动时调用)
VelopackApp.Build().Run();
// 检查更新
var mgr = new UpdateManager("https://.../updates");
var newVersion = await mgr.CheckForUpdatesAsync();
// 下载更新
await mgr.DownloadUpdatesAsync(newVersion);
// 应用并重启
mgr.ApplyUpdatesAndRestart(newVersion);
```
## 打包命令
```bash
# 1. 发布应用
dotnet publish -c Release -o ./publish --self-contained false -r win-x64
# 2. Velopack 打包
vpk pack -u "henlo_migration" -v "1.0.002" -p "./publish" -e "恒诺迁移工具.exe" -o "./releases"
```
## 服务器部署
将 `releases/` 目录下的文件上传到:
```
http://zjhenlo.henlo.net:8878/henlo_migration/auto_update/
```
Velopack 会自动读取该目录下的 `RELEASES` 文件检查更新。
## 优势
1. **Rust 核心** → Updater 完全不需要 .NET Runtime
2. **Delta 更新** → 只下载变更文件
3. **自动回滚** → 更新失败自动恢复旧版本
4. **后台静默更新** → 下次启动时自动应用
5. **经过大规模验证** → osu!、STranslate 等大牌在用
## 待办
- [ ] 测试打包流程
- [ ] 配置服务器更新目录
- [ ] 测试完整更新流程
- [ ] 更新 CI/CD 脚本(如有)
+432
View File
@@ -0,0 +1,432 @@
# Velopack 操作手册 — 恒诺迁移工具(便携模式)
## 一、Velopack 是什么
Velopack 是一个**自动更新框架**,核心功能:
1. **打包** — 把程序编译输出打包成更新包(.nupkg)
2. **自动更新** — 程序启动时自动检查服务器,发现新版本就下载并提示用户重启
**核心优势**:更新器用 Rust 编写,不需要 .NET Runtime,彻底解决 AutoUpdater.NET 的 .NET 8 依赖问题。
**本模式**:便携模式(`--noInst`),不生成安装包,用户直接解压 ZIP 使用。
---
## 二、项目结构(打包相关)
```
henlo_migration_wpf10/
├── henlo_migration_wpf10.csproj # 项目文件(已添加 Velopack 包)
│ └── <Version>1.0.2</Version> # 【版本号唯一来源】
├── App.xaml.cs # 启动时初始化 Velopack
├── Views/HomeWindow.xaml.cs # "检查更新"按钮逻辑
├── publish/ # 【发布输出目录】dotnet publish 生成
├── releases/ # 【打包输出目录】vpk pack 生成
│ ├── henlo_migration-1.0.2-full.nupkg # 更新包(上传到服务器)
│ ├── henlo_migration-win-Portable.zip # 便携版(给用户第一次使用)
│ ├── RELEASES # 更新索引文件(上传到服务器)
│ ├── assets.win.json # 资源清单
│ └── releases.win.json # 发布配置
└── pack.bat # 一键打包脚本(已创建)
```
---
## 三、版本号管理(重要)
### 唯一来源:csproj 文件
**版本号只存在于一个地方**:`henlo_migration_wpf10.csproj` 中的 `<Version>` 标签
```xml
<PropertyGroup>
<Version>1.0.2</Version> <!-- 唯一需要修改的地方 -->
</PropertyGroup>
```
### 版本号格式(SemVer2)
```
主版本.次版本.补丁
```
| 格式 | 示例 | 说明 |
|------|------|------|
| ✅ 正确 | `1.0.2`、`1.1.0`、`2.0.0` | 三段数字,无前导零 |
| ❌ 错误 | `1.0.02`、`1.0.002` | 不能前导零 |
| ❌ 错误 | `1.0` | 必须是三段 |
### 版本号递增规则
| 位置 | 什么时候改 | 示例 |
|------|-----------|------|
| 补丁(第3位) | Bug 修复 | `1.0.1` → `1.0.2` |
| 次版本(第2位) | 新增功能 | `1.0.2` → `1.1.0` |
| 主版本(第1位) | 重大更新/不兼容 | `1.1.0` → `2.0.0` |
**重要**:版本号必须递增,不能回退(Velopack 不允许降级)。
### 版本号同步机制
```
csproj <Version> 标签
│
├──→ 程序集版本(编译时自动嵌入 DLL)
├──→ 程序运行时显示(SysConfig.version 从程序集读取)
└──→ Velopack 打包版本(pack.bat 自动读取)
```
**只需要改一处**,其他地方全部自动同步。
---
## 四、发布流程(完整步骤)
### 步骤 1:修改版本号
打开 `henlo_migration_wpf10.csproj`,修改 `<Version>`:
```xml
<!-- 修改前 -->
<Version>1.0.1</Version>
<!-- 修改后 -->
<Version>1.0.2</Version>
```
**注意**:
- 只改这个数字,不要改其他地方
- 确保新版本号比旧版本大
- 保存文件
---
### 步骤 2:编译发布
```bash
# 进入项目目录
cd D:\work\恒诺\长期支持\恒诺迁移工具\henlo_migration_wpf10
# 发布(Release 模式,输出到 publish/ 目录)
dotnet publish henlo_migration_wpf10.csproj -c Release -o publish --self-contained false -r win-x64
```
**参数说明**:
| 参数 | 含义 |
|------|------|
| `-c Release` | Release 模式(优化过的,体积小) |
| `-o publish` | 输出到 `publish/` 目录 |
| `--self-contained false` | 不包含 .NET Runtime(假设用户已装 .NET 10) |
| `-r win-x64` | 目标平台:Windows x64 |
**输出**:`publish/` 目录下生成完整的程序文件(.exe、.dll 等)
---
### 步骤 3:Velopack 打包(便携模式)
```bash
# 打包(使用 vpk 命令行工具,--noInst 表示不生成安装包)
vpk pack -u henlo_migration -v 1.0.2 -p publish -e 恒诺迁移工具.exe -o releases --noInst
```
**参数说明**:
| 参数 | 含义 |
|------|------|
| `-u henlo_migration` | 应用唯一标识符(URL 友好的名字) |
| `-v 1.0.2` | 版本号(必须是 SemVer2 格式) |
| `-p publish` | 输入目录(步骤 2 的输出) |
| `-e 恒诺迁移工具.exe` | 程序入口 EXE 文件名 |
| `-o releases` | 输出目录(打包结果放这里) |
| `--noInst` | **不生成安装包**(便携模式) |
**输出**:`releases/` 目录下生成 5 个文件(无 Setup.exe)
---
### 步骤 4:上传到服务器
把以下文件上传到更新服务器:
```
http://zjhenlo.henlo.net:8878/henlo_migration/auto_update/
├── henlo_migration-1.0.2-full.nupkg ← 必须(更新包)
└── RELEASES ← 必须(更新索引)
```
**注意**:
- 每次发布新版本,上传新的 `.nupkg` 文件即可
- `RELEASES` 文件会被 Velopack 自动更新(包含所有版本列表)
- 不需要上传 `Portable.zip` 到服务器(那是给用户第一次下载用的)
---
## 五、一键打包脚本
已创建 `pack.bat`,用法:
```batch
# 直接运行,版本号自动从 csproj 读取
pack.bat
```
**脚本内容**:
```batch
@echo off
setlocal enabledelayedexpansion
REM Velopack pack script (portable mode, no installer)
REM Reads <Version> from csproj automatically
set "PROJECT_DIR=%~dp0"
set "PUBLISH_DIR=%PROJECT_DIR%publish"
set "RELEASE_DIR=%PROJECT_DIR%releases"
set "CSPROJ=%PROJECT_DIR%henlo_migration_wpf10.csproj"
REM Read <Version> from csproj via PowerShell (handles UTF-8)
for /f "usebackq delims=" %%a in (`powershell -NoProfile -Command "[regex]::Match(([System.IO.File]::ReadAllText('%CSPROJ%', [System.Text.Encoding]::UTF8)), '<Version>(.+?)</Version>').Groups[1].Value"`) do set "VERSION=%%a"
if "!VERSION!"=="" (
echo ERROR: Cannot read version from csproj
exit /b 1
)
echo ========================================
echo Henlo Migration Tool - Velopack Pack
echo Version: !VERSION!
echo ========================================
echo [1/3] Cleanup...
if exist "!PUBLISH_DIR!" rmdir /s /q "!PUBLISH_DIR!"
if exist "!RELEASE_DIR!" rmdir /s /q "!RELEASE_DIR!"
echo [2/3] dotnet publish...
dotnet publish "%CSPROJ%" -c Release -o "!PUBLISH_DIR!" --self-contained false -r win-x64
if errorlevel 1 (
echo ERROR: dotnet publish failed!
exit /b 1
)
echo [3/3] vpk pack (--noInst)...
vpk pack -u "henlo_migration" -v "!VERSION!" -p "!PUBLISH_DIR!" -e "恒诺迁移工具.exe" -o "!RELEASE_DIR!" --noInst
if errorlevel 1 (
echo ERROR: vpk pack failed!
exit /b 1
)
echo ========================================
echo Pack complete!
echo Output:
echo henlo_migration-win-Portable.zip
echo henlo_migration-!VERSION!-full.nupkg
echo RELEASES
echo Server deploy to:
echo http://zjhenlo.henlo.net:8878/henlo_migration/auto_update/
echo ========================================
endlocal
```
---
## 五点五、重要:中文路径编码问题
### 问题描述
项目路径包含中文字符(如 `D:\work\恒诺\...`),在某些场景下会导致编码问题:
| 工具/场景 | 是否受影响 | 说明 |
|----------|----------|------|
| **pack.bat 双击运行** | ❌ 正常 | CMD 直接执行,编码正确 |
| **手动执行 PowerShell** | ❌ 正常 | PowerShell 能正确处理 UTF-8 |
| **通过 AI Agent exec 工具** | ⚠️ **受影响** | 中文路径可能被损坏,导致命令执行失败 |
### 问题表现
当 exec 工具执行包含中文路径的命令时,可能出现:
```
# 预期命令
dir /b "D:\work\恒诺\长期支持\..."
# 实际执行的命令(路径被截断)
dir /b "D:\b"
```
### 解决方案
如果需要通过 AI Agent 执行涉及中文路径的操作,使用以下策略:
1. **写入脚本文件再执行**
```
# 不要直接执行带中文路径的命令
❌ exec: dir "D:\work\恒诺\..."
# 应先写脚本文件,再执行简单路径
✅ write: 将 Node.js/Python 脚本写入 _helper.js/_helper.py
✅ exec: node "D:\work\恒诺\...\_helper.js" # 路径简单时可行
# 或使用英文路径的项目目录
```
2. **使用相对路径**(如果在项目目录内操作)
```
cd /d "D:\work\恒诺\长期支持\恒诺迁移工具\henlo_migration_wpf10"
dir /b publish # 使用相对路径避免中文
```
3. **创建符号链接**(临时方案)
```cmd
mklink /D C:\henlo "D:\work\恒诺\长期支持\恒诺迁移工具"
# 之后操作使用 C:\henlo\... 路径
```
### 最佳实践
- **打包操作**:直接在项目目录双击 `pack.bat` 运行,不要通过 AI Agent 执行
- **文件操作**:AI Agent 使用 `write`/`read` 工具(这些工具能正确处理中文路径)
- **命令执行**:尽量使用不含中文字符的路径,或先写脚本再执行
---
## 六、打包目录说明
### 输入目录(`-p` 参数)
```
publish/ ← 你指定的输入目录
├── 恒诺迁移工具.exe ← 入口程序(-e 参数指定)
├── 恒诺迁移工具.dll
├── 各种依赖 DLL
├── HandyControl.dll
├── Velopack.dll
└── ...其他文件
```
**来源**:`dotnet publish` 的输出
### 输出目录(`-o` 参数)
```
releases/ ← 打包结果
├── henlo_migration-1.0.2-full.nupkg # 完整更新包(上传服务器)
├── henlo_migration-win-Portable.zip # 便携版(给用户第一次用)
├── RELEASES # 版本索引(上传服务器)
├── assets.win.json # 资源清单
└── releases.win.json # 发布配置
```
**注意**:没有 `Setup.exe`(因为用了 `--noInst`)
---
## 七、用户侧体验
### 第一次使用(新用户)
1. 从服务器下载 `henlo_migration-win-Portable.zip`
2. 解压到任意目录(如 `D:\恒诺迁移工具\`)
3. 双击 `恒诺迁移工具.exe` 运行
### 以后更新(自动)
1. 打开程序(旧版本)
2. Velopack 自动检查服务器 `RELEASES` 文件
3. 发现新版本 → 后台下载 `.nupkg` 更新包
4. 弹出提示:"发现新版本 1.0.2,是否重启更新?"
5. 用户点击"是" → 程序关闭 → 自动安装更新 → 重启程序
6. 打开后就是新版本
### 手动检查更新
用户也可以点击菜单「帮助」→「检查更新」手动触发。
---
## 八、服务器配置
### 目录结构
```
/var/www/henlo_migration/auto_update/ # Nginx 根目录
├── henlo_migration-1.0.0-full.nupkg # 旧版本(保留)
├── henlo_migration-1.0.1-full.nupkg # 旧版本(保留)
├── henlo_migration-1.0.2-full.nupkg # 当前版本
└── RELEASES # 版本索引(自动维护)
```
**注意**:不需要放 `Setup.exe` 和 `Portable.zip` 在服务器上。
### RELEASES 文件示例
```
9467F3A6D8E1B2C henlo_migration-1.0.0-full.nupkg 5915018
A7B8C9D0E1F2A3B henlo_migration-1.0.1-full.nupkg 5915018
C3D4E5F6A7B8C9D henlo_migration-1.0.2-full.nupkg 5915018
```
**注意**:不要手动修改 `RELEASES` 文件,Velopack 会自动维护。
---
## 九、常见问题
### Q1:打包时提示 "VelopackApp.Run() was found in OnStartup"
**原因**:Velopack 建议把初始化代码放在 `Main()` 方法开头,而不是 WPF 的 `OnStartup`。
**解决**:可以忽略(当前位置也能工作),或者按提示移到 `Main()` 里。
### Q2:用户无法自动更新
**检查清单**:
1. 服务器 URL 是否正确?(`App.xaml.cs` 中的 `UpdateUrl`)
2. `RELEASES` 文件是否在服务器上?
3. `.nupkg` 文件是否上传到服务器?
4. 防火墙是否允许访问服务器?
5. 版本号是否递增?(Velopack 不允许降级)
### Q3:如何回滚版本?
Velopack **不支持回滚**。如果新版本有问题:
1. 修复 bug
2. 发布更高版本号(如 1.0.3)
3. 用户更新到 1.0.3
### Q4:用户第一次如何获取程序?
把 `henlo_migration-win-Portable.zip` 发给用户:
- 通过 QQ、微信、邮件发送
- 或放在网盘/服务器上下载
- 用户下载后解压即可使用
---
## 十、发布检查清单
每次发布前检查:
- [ ] 代码已提交 Git
- [ ] **版本号已更新**(只改 `csproj` 里的 `<Version>`)
- [ ] `dotnet publish` 成功
- [ ] `vpk pack --noInst` 成功(或 `pack.bat` 成功)
- [ ] 测试程序能正常启动
- [ ] 上传 `.nupkg` 和 `RELEASES` 到服务器
- [ ] 测试自动更新流程
- [ ] 把 `Portable.zip` 发给需要的新用户
---
## 十一、命令速查表
| 操作 | 命令 |
|------|------|
| 修改版本号 | 编辑 `henlo_migration_wpf10.csproj` 中的 `<Version>` |
| 编译发布 | `dotnet publish -c Release -o publish --self-contained false -r win-x64` |
| Velopack 打包(便携模式) | `vpk pack -u henlo_migration -v 1.0.2 -p publish -e 恒诺迁移工具.exe -o releases --noInst` |
| 一键打包 | `pack.bat`(版本号自动从 csproj 读取) |
| 安装 vpk 工具 | `dotnet tool install -g vpk` |
| 更新 vpk 工具 | `dotnet tool update -g vpk` |
---
*文档版本:2026-04-22(便携模式)*
*适用项目:恒诺迁移工具 WPF*