# Velopack 操作手册 — 恒诺迁移工具(便携模式) ## 一、Velopack 是什么 Velopack 是一个**自动更新框架**,核心功能: 1. **打包** — 把程序编译输出打包成更新包(.nupkg) 2. **自动更新** — 程序启动时自动检查服务器,发现新版本就下载并提示用户重启 **核心优势**:更新器用 Rust 编写,不需要 .NET Runtime,彻底解决 AutoUpdater.NET 的 .NET 8 依赖问题。 **本模式**:便携模式(`--noInst`),不生成安装包,用户直接解压 ZIP 使用。 --- ## 二、项目结构(打包相关) ``` henlo_migration_wpf10/ ├── henlo_migration_wpf10.csproj # 项目文件(已添加 Velopack 包) │ └── 1.0.2 # 【版本号唯一来源】 ├── 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` 中的 `` 标签 ```xml 1.0.2 ``` ### 版本号格式(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 标签 │ ├──→ 程序集版本(编译时自动嵌入 DLL) ├──→ 程序运行时显示(SysConfig.version 从程序集读取) └──→ Velopack 打包版本(pack.bat 自动读取) ``` **只需要改一处**,其他地方全部自动同步。 --- ## 四、发布流程(完整步骤) ### 步骤 1:修改版本号 打开 `henlo_migration_wpf10.csproj`,修改 ``: ```xml 1.0.1 1.0.2 ``` **注意**: - 只改这个数字,不要改其他地方 - 确保新版本号比旧版本大 - 保存文件 --- ### 步骤 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 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 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)), '(.+?)').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` 里的 ``) - [ ] `dotnet publish` 成功 - [ ] `vpk pack --noInst` 成功(或 `pack.bat` 成功) - [ ] 测试程序能正常启动 - [ ] 上传 `.nupkg` 和 `RELEASES` 到服务器 - [ ] 测试自动更新流程 - [ ] 把 `Portable.zip` 发给需要的新用户 --- ## 十一、命令速查表 | 操作 | 命令 | |------|------| | 修改版本号 | 编辑 `henlo_migration_wpf10.csproj` 中的 `` | | 编译发布 | `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*