Files

13 KiB
Raw Permalink Blame History

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> 标签

<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>:

<!-- 修改前 -->
<Version>1.0.1</Version>

<!-- 修改后 -->
<Version>1.0.2</Version>

注意:

  • 只改这个数字,不要改其他地方
  • 确保新版本号比旧版本大
  • 保存文件

步骤 2:编译发布

# 进入项目目录
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 打包(便携模式)

# 打包(使用 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,用法:

# 直接运行,版本号自动从 csproj 读取
pack.bat

脚本内容:

@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. 创建符号链接(临时方案)

    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