Initial import of WPF migration tool
This commit is contained in:
@@ -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*
|
||||
Reference in New Issue
Block a user