GeneralUpdate.Tools
这是什么
GeneralUpdate.Tools 是一个基于 Avalonia 12 开发的跨平台桌面工具(Windows / Linux / macOS),用于在软件发布流程中生成和管理补丁包、扩展包、版本清单以及执行本地更新仿真。它不替代你的 CI/CD 系统,而是把”打包、校验、验证”这些重复劳动收敛到一个可视化工具中。
Tools 是桌面 GUI 工具,适合开发者在本地交互式地生成补丁、验证更新。如果你需要在 CI/CD 流水线中自动化补丁生成,可以直接调用 GeneralUpdate.Core.Pipeline.DiffPipeline.CleanAsync() —— GUI 和脚本走的是同一条代码路径。
仓库地址:https://github.com/GeneralLibrary/GeneralUpdate.Tools
下载与运行
方式一:从源码运行(推荐开发者)
当前工具基于 .NET 10 构建。确保本机安装了 .NET 10 SDK:
git clone https://github.com/GeneralLibrary/GeneralUpdate.Tools.git
cd GeneralUpdate.Tools\src
dotnet run --project GeneralUpdate.Tools.csproj
方式二:下载预编译版本
前往 GeneralUpdate.Tools Releases 下载对应平台的可执行文件,直接运行即可。
Simulation 模块内部会调用
dotnet publish构建测试应用,因此使用仿真功能时必须安装 .NET SDK。Mobile 模块的项目模式(Build & Locate)也会调用dotnet publish,同样需要 .NET SDK。仅运行 Patch / Extension / OSS / Config 模块以及 Mobile 的文件模式则不需要。
七个模块速览
| 模块 | 你提供 | 工具产出 | 下游消费者 |
|---|---|---|---|
| Patch | 旧版本目录 + 新版本目录 | {name}.zip(含 .patch 文件、新文件、generalupdate.delete.json) | Server、OSS/CDN、Core Upgrade 进程 |
| Extension | 扩展源目录 + 元数据 | {name}_{version}.zip(含 manifest.json) | GeneralUpdate.Extension 组件 |
| OSS Config | 包名、版本、下载 URL、本地 ZIP(计算 Hash) | oss_config.json(版本数组) | OSS 客户端、对象存储 发布流程 |
| Config | Client/Upgrade 的 .csproj | generalupdate.manifest.json + sample_output/ 发布目录 | Client/Upgrade 启动引导 |
| Simulation | 旧版本目录 + 补丁 ZIP | 本地更新服务 + simulation_report.md | 发布前质量把关 |
| Hash | 本地文件(ZIP) | SHA256 小写十六进制字符串 | 完整性校验、服务端版本记录 |
| Mobile | APK/AAB 文件或 MAUI/Avalonia Android 的 .csproj | mobile_version_{timestamp}.json 版本记录 | 移动端更新服务端、GeneralUpdate.Avalonia/Maui 组件 |
Patch:生成补丁包
解决什么问题
当你发布了一个新版本,用户不想下载整个安装包。Patch 模块比较旧版本目录和新版本目录,只输出变更内容:修改过的文件生成二进制差分 .patch,新增文件直接复制,删除的文件写入清单。差分包通常远小于完整发布目录。
输入
| 字段 | 必填 | 说明 |
|---|---|---|
| Old Directory | ✅ | 用户当前安装的旧版本发布目录,例如 publish\v1.0.0 |
| New Directory | ✅ | 准备发布的新版本目录,例如 publish\v2.0.0 |
| Package Name | ❌ | 输出 ZIP 文件名(不含 .zip),为空时自动生成 patch_yyyyMMddHHmmss |
| Version | ✅ | 目标版本号,格式 MAJOR.MINOR.PATCH(如 2.0.0)或 MAJOR.MINOR.PATCH-prerelease+build |
| Output Directory | ❌ | ZIP 输出目录,为空时输出到桌面 |
工具内部做了什么
- 加密文件检测:扫描 old/new 目录中的二进制文件,检测是否存在加壳(如 Themida、VMProtect)或加密签名。被检测到的文件将标记警告——此类文件无法生成有效差分补丁,将以全量文件形式打包。
- 校验 old/new 目录存在、version 格式合法。
- 创建临时目录
gupatch_yyyyMMddHHmmss。 - 递归比较 old/new:修改文件 → 生成
.patch二进制差分;新增文件 → 直接复制;删除文件 → 记录 hash 到generalupdate.delete.json。 - 将临时目录压缩为
{PackageName}.zip。 - 删除临时目录,ZIP 保留在 Output Directory。
关于加密文件:加壳工具(Themida、VMProtect 等)、代码混淆或加密的二进制文件,因文件哈希在新旧版本间完全不同,差分算法对其无效。此类文件检测到后将直接以全量形式打包,而不会生成
.patch差分。建议在发布前对原始文件进行去壳/解密处理,以获得 最优的补丁体积。
底层调用的是 GeneralUpdate.Core.Pipeline.DiffPipeline.CleanAsync(oldDir, newDir, patchDir),和你的 CI 脚本走的是同一条代码路径。
输出
{OutputDirectory}/{PackageName}.zip
├── changed.dll.patch ← 二进制差分
├── new_file.dll ← 新增文件(保持目录结构)
└── generalupdate.delete.json ← 删除清单
下游如何使用
- 把 ZIP 放到 Server 的
wwwroot/packages/目录,更新versions.json中的Url和Hash - 或上传到 OSS/CDN,把下载链接写入
oss_config.json - Core Upgrade 进程下载 ZIP 后,
DiffPipeline.DirtyAsync根据.patch和删除清单完成更新
Extension:打包扩展
解决什么问题
如果你使用 GeneralUpdate.Extension 组件管理插件/扩展,每次发布新扩展都需要手动构建标准格式的 ZIP 包并生成 manifest.json。Extension 模块把你从手工压缩和手写 JSON 中解放出来。
输入
| 字段 | 必填 | 说明 |
|---|---|---|
| Name | ✅ | 扩展唯一标识,建议小写+连字符,如 my-data-exporter |
| Version | ✅ | 语义化版本,如 1.0.0 |
| Description | ❌ | 扩展功能描述 |
| Publisher | ❌ | 发布者名称 |
| License | ❌ | 许可证标识,如 MIT |
| Extension Directory | ✅ | 扩展源文件目录,点击 Pick 选择文件 夹 |
| Export Directory | ❌ | 输出目录,为空时输出到桌面 |
| Custom Properties | ❌ | 自定义键值对,写入 manifest.json.customProperties |
工具内部做了什么
- 校验目录存在、version 格式合法。
- 将 Extension Directory 中所有文件打包为 ZIP。
- 在 ZIP 根目录写入
manifest.json。
输出
{ExportDirectory}/{Name}_{Version}.zip
├── manifest.json ← 扩展元数据
├── bin/
│ └── MyExtension.dll
├── resources/
└── ...