黑金古刀-永劫助手(BlackGoldAncientSword)——《永劫无间》战绩查询与队友识别桌面工具

📅 2026/7/4 4:14:28
黑金古刀-永劫助手(BlackGoldAncientSword)——《永劫无间》战绩查询与队友识别桌面工具
中文 | English黑金古刀-永劫助手BlackGoldAncientSwordGitHub 仓库https://github.com/ViewSuSu/BlackGoldAncientSwordGitee 镜像https://gitee.com/SususuChang/BlackGoldAncientSword一款基于 WPF .NET 10 的开源桌面工程项目围绕《永劫无间》公开的对局数据 API 做可视化展示并系统化演示 Prism 模块化、Windows Graphics Capture、进程内 OCR 推理、Roslyn 源码生成、独立自更新等桌面工程实践。该项目受到 Zzaphkiel/Seraphine 的鼓舞感谢先驱者们做出的贡献。项目介绍视频 项目介绍视频Bilibili点击上方按钮观看项目介绍视频。下载 下载最新版本安装包点击上方按钮即可直接下载最新版本的 .exe 安装包。用户手册简介黑金古刀-永劫助手BlackGoldAncientSword是一款运行在 Windows 10/11 上的开源 WPF 桌面项目演示如何用 .NET 10 WPF Prism 组合搭建一个模块化、可自更新、内置离线 OCR 推理的完整桌面应用。项目本身也是一份公开数据可视化工具通过第三方公开 API 拉取并展示玩家的历史对局统计支持按三排 / 双排 / 单排及排位 / 匹配 / 天人模式的完整数据展示。战绩查询战绩页面通过第三方公开 APIhttps://naraka.drivod.top/拉取指定玩家的公开对局统计数据并在 WPF 界面按赛季 / 模式 / 队伍规模维度进行结构化展示赛季数据总览K/D、第一率、前五率、场均击败、场均治疗、场均助攻、场均生存最高记录最高击败、最高治疗、最高助攻、最高伤害、最多振刀段位信息当前赛季段位分数与段位名称天选模式含星数最近 10 场对局每局英雄、模式、击败/伤害、段位分变化含 ± 差值、荣誉称号支持切换赛季、模式类别排位 / 匹配 / 天人和队伍规模三排 / 双排 / 单排。战绩点击玩家昵称旁的复制按钮可快速复制昵称或 UID。—## 队伍信息展示本模块演示如何用 Windows Graphics Capture API 对指定桌面窗口进行截图交给进程内 ONNX Runtime 跑 PP-OCRv5 模型识别文字再把识别结果对接到上游公开 API 做并列展示。通过 OCR 自动读取截图中的文字无需手动输入支持三排 / 双排 / 单排队伍支持排位 / 匹配 / 天人模式切换多份识别结果并排展示方便对比状态切换后锁定当前展示内容避免重复触发 OCR队伍信息识别 1队伍信息识别 2 可点击重新识别按钮手动触发一轮 OCR。若识别到的文字有误可直接修改后重新查询。设置设置页面集中管理应用配置数据保存路径战绩数据的本地存储目录支持自定义 旧数据自动迁移缓存路径图片缓存目录含缓存大小显示与一键清理语言支持 简体中文 / English / 繁體中文关闭行为点击关闭按钮时的默认行为可选每次询问 / 最小化到任务栏 / 最小化到系统托盘 / 直接退出并支持记住选项英雄选择时的右下角队伍提示弹窗开关控制检查更新手动检查与下载新版本调用独立的 Update 程序在线更新详见下文当前版本显示版本号设置在线更新助手在启动时和设置 → 检查更新中均会自动比对 GitHub Releases 的最新版本。检测到新版本时会弹出更新提示页面点击在线更新即可主程序拉起独立的BlackGoldAncientSword.Update.exe更新器并传入下载地址、安装目录、主程序文件名等参数更新器下载新版 zip → 解压 → 全量覆盖安装目录 → 重新拉起主程序 → 自身退出。更新器与主程序完全解耦不引用 App / Framework / Modules因此覆盖文件时不会被 DLL 锁定。其他功能系统托盘程序支持最小化到系统托盘长时间后台运行不占用任务栏。右键托盘图标可快速恢复窗口或退出。关闭提示托盘图标显示在线状态点击关闭按钮时弹出确认对话框提醒退出后将不再刷新数据常见问题 FAQ Q查询失败或数据有延迟数据来自第三方公开 APIhttps://naraka.drivod.top/本项目仅做展示。查询失败通常是上游 API 服务本身的问题本项目暂无法直接处理。QOCR 识别失败或不准确OCR 使用 Windows Graphics Capture API 截取指定窗口的画面目前只支持屏幕分辨率与窗口分辨率一致的情况。当两侧出现黑边时识别效果会受影响建议使用与显示器同分辨率的全屏窗口运行。OCR 对少量特殊字符可能识别不完整可以在界面上手动修正后再触发查询。Q为什么安装包/程序这么大程序采用自包含发布self-contained内置了 .NET 运行时无需用户额外安装 .NET 环境即可直接运行。此外程序自带的 OCR 文字识别引擎依赖PP-OCRv5 ONNX 模型约 22MB ONNX Runtime 原生库 SkiaSharp 图像编解码库这部分总计约 50MB。这些原生 AI/视觉组件连同 .NET 运行时占了安装包的大部分体积。没有它们就无法实现队友昵称的自动截图识别所以庞大是必要的代价 。v1.0.0.3 起OCR 引擎已从 PaddleOCR-json 子进程方案含约 150MB Paddle Inference MKL OpenCV 原生 dll切换到 RapidOcrNet 进程内 ONNX Runtime 方案识别模型升级至 PP-OCRv5安装包整体减重约 100MB对特殊字符如日文假名、拉丁扩展的覆盖也大幅提升。Q为什么屏幕会出现黄色边框黄色边框是程序进行窗口截图时的视觉提示属于正常现象。Q如果被杀毒软件提示怎么办因为该程序没有被签名过所以可能会被 360 等程序识别为病毒或者其他。可以关闭杀毒软件后重新打开。**Q在线更新失败怎么办**更新器BlackGoldAncientSword.Update.exe独立于主程序运行常见失败原因网络无法访问下载源、安装目录权限不足、杀毒软件拦截覆盖。可从 Releases 页面直接下载安装包手动覆盖安装。免责声明 BlackGoldAncientSword黑金古刀未经 24 Entertainment 或网易认可不代表 24 Entertainment、网易或任何官方参与制作或管理《永劫无间》产品的人的观点或意见。《永劫无间》及其所有关联产物均为 24 Entertainment / 网易的商标或注册商标。点个 Star 支持我们 ⭐开发者文档解决方案概览src/BlackGoldAncientSword.slnx共包含11 个项目8 个类库 3 个可执行程序主程序 App、独立更新器 Update、离线下载器 Downloader。┌────────────────────────────────────────────────────────┐ │ BlackGoldAncientSword.App │ ← WPF 主程序入口WinExe │ (Shell / MainWindow / Tray) │ └──────────┬─────────────────────────────────────────┬───┘ │ 启动外部进程 │ ▼ │ ┌──────────────────────────┐ │ │ BlackGoldAncientSword. │ │ │ Update (独立更新器,WinExe)│ │ │ 下载/解压/覆盖/重启 │ │ └──────────────────────────┘ │ │ ┌──────────────────────────┐ ← 独立发布非主程序运行时依赖 │ BlackGoldAncientSword. │ │ Downloader (离线下载器, │ Gitee 分卷安装包下载 → │ WinExe) │ 拉起 Setup 完成安装 └──────────────────────────┘ │ ┌─────────────────────┬──────────────────────┘ │ │ ▼ ▼ ▼ ┌────────────┐ ┌──────────────┐ ┌───────────┐ │ Modules │ │ Framework │ │ Resources │ │ (10 个 UI │ ◄────► │ (Core 13 │ ◄──────│ (多语言 │ │ 页面模块) │ │ 个服务接口) │ │ XAML图) │ └─────┬──────┘ └──────┬───────┘ └───────────┘ │ │ │ ┌────────┴───────┐ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────┐ ┌────────────────────┐ │ GameMonitor │ │ ScreenCapture│ │ Framework. │ │ (进程/日志/ │ │ (WGC API │ │ SourceGenerator │ │ 状态机) │ │ 原生 DLL) │ │ (编译期生成 HTTP) │ └──────┬───────┘ └──────┬───────┘ └────────────────────┘ │ │ ▼ ▼ ┌──────────────┐ ┌──────────────────┐ │ Ocr │ │ RapidOcrNet │ │ (进程内 ONNX)│ │ PP-OCRv5 (ONNX) │ └──────────────┘ └──────────────────┘项目分层层项目输出类型职责主程序BlackGoldAncientSword.AppWinExeWPF 应用入口、主窗口、侧边栏导航、托盘、启动更新器、启动期后台预热 OCR更新器BlackGoldAncientSword.UpdateWinExe独立在线更新进程零业务依赖仅 HandyControl离线下载器BlackGoldAncientSword.DownloaderWinExe独立单文件 exe从 Gitee release 顺序流式下载分卷安装包 → 拉起 Setup.exe → 自身退出。零 API 依赖走 302 CDNUI 模块BlackGoldAncientSword.ModulesClassLib10 个 PrismIModule页面按需加载核心框架BlackGoldAncientSword.FrameworkClassLibMVVM 基类、Prism 基础设施、服务抽象与实现、HTTP API游戏监控BlackGoldAncientSword.GameMonitorClassLib进程检测、Player.log 解析、战局状态机屏幕捕获BlackGoldAncientSword.ScreenCaptureClassLibWindows Graphics Capture API SharpDX含原生 wgc_capture.dllOCR 引擎BlackGoldAncientSword.OcrClassLibRapidOcrNetPP-OCRv5 ONNX进程内推理封装资源BlackGoldAncientSword.ResourcesClassLib多语言 XAML 资源字典、图标、图片源码生成BlackGoldAncientSword.Framework.SourceGeneratorRoslyn Analyzer编译期从 JSON 定义生成 HTTP 客户端与测试代码测试BlackGoldAncientSword.TestsxUnitOCR、屏幕捕获、游戏监控、HTTP、更新流程测试技术栈类别技术 / 库用途运行时.NET 10.0 (net10.0-windows)目标框架UIWPF HandyControl 3.5桌面界面与控件库主题自定义 ModernTheme青瓷竹青护眼配色淡雅护眼浅绿底 竹青深绿点缀 深墨字长时间阅读舒适MVVM 框架Prism 8.1 (Prism.DryIoc)DI 容器、区域导航、模块化HTTP编译期源码生成器从api-definitions.json自动生成强类型 API 客户端对象映射Mapster 7.4DTO ↔ ViewModelJSONSystem.Text.Json含源码生成上下文序列化 / 反序列化已全量替换 Newtonsoft.Json屏幕捕获SharpDX.Direct3D11 原生 WGC DLL (C/WinRT)游戏窗口截图OCRRapidOcrNet 2.0.0 ONNX Runtime 1.24进程内推理PP-OCRv5 模型多语言文字识别中/英/日/拉丁/西里尔等单模型覆盖图像处理SkiaSharp 3.119OCR 入口 byte[] → SKBitmap 解码系统托盘Hardcodet.NotifyIcon.Wpf托盘图标与菜单测试xUnit Moq单元测试与集成测试打包Self-Contained PublishSingleFileApp、Updater 均为单文件独立部署 (win-x64)安装包Inno Setup生成BlackGoldAncientSword-{version}-win-x64-Setup.exe目录结构src/ ├── BlackGoldAncientSword.App/ # WPF 主程序入口WinExe │ ├── App.xaml / App.xaml.cs # 应用入口、Prism 启动配置 │ └── Shell/ │ ├── MainWindow.xaml(.cs) # 主窗口侧边栏 导航 托盘 │ └── MainWindowViewModel.cs # 导航命令、游戏状态、更新检测 │ ├── BlackGoldAncientSword.Update/ # 独立在线更新器WinExe零业务依赖 │ ├── App.xaml(.cs) # 入口解析 --url / --target / --main-exe │ ├── Services/ │ │ ├── UpdateOptions.cs # 命令行参数模型 │ │ └── UpdaterRunner.cs # 编排下载→解压→关主程序→覆盖→重启 │ ├── Shell/UpdateWindow.xaml(.cs) # 进度窗口 │ └── ViewModels/UpdateViewModel.cs # 进度与状态绑定 │ ├── BlackGoldAncientSword.Downloader/ # 离线安装包下载器WinExe独立单文件 │ ├── App.xaml(.cs) # 入口进程级兜底清理临时目录 │ ├── Services/ │ │ ├── DownloaderRunner.cs # 编排查 Gitee latest → 顺序流式下载分卷 → 拉起 Setup │ │ ├── GiteeAssetsFetcher.cs # 走 302 CDN零 Gitee API 依赖避 rate limit │ │ └── InstallerForegrounder.cs # 拉起主 Setup exe 并前台化 │ ├── Shell/DownloadWindow.xaml(.cs) # 下载进度窗口进度 4-stat 实时刷新 │ └── ViewModels/DownloadViewModel.cs │ ├── BlackGoldAncientSword.Framework/ # 核心框架 │ ├── Core/ │ │ ├── Attributes/ # ComponentAttributeDI 自动注册标记 │ │ ├── Bases/ # ViewModelBase、PrismApplicationBase 等 │ │ ├── Consts/ # GlobalConstant、PageNames │ │ ├── Events/ # GameStatusChanged、SettingsChanged、TipMessageEvent │ │ ├── Extensions/ # 扩展方法与 Value Converter │ │ └── Infrastructure/ # IMainContentNavigationService / MainContentNavigator │ ├── Http/ │ │ ├── Definitions/ │ │ │ ├── api-definitions.json # API 端点 / 请求 / 响应定义→ 源码生成 │ │ │ └── enums.json # 枚举定义 │ │ └── JsonFlexibleStringConverter.cs # System.Text.Json 容错转换器 │ ├── Services/ │ │ ├── Abstractions/ # 13 个服务接口见下表 │ │ └── Implementation/ # 服务实现 │ ├── Themes/Generic.xaml # HandyControl 主题 │ └── UI/Controls/ # 自定义 WPF 控件DataGridWrapPanel 等 │ ├── BlackGoldAncientSword.Framework.SourceGenerator/ # Roslyn 源码生成器 │ ├── ApiDefinitionsParser.cs # 解析 api-definitions.json │ ├── EnumSourceGenerator.cs # 生成枚举类型 │ ├── HttpApiSourceGenerator.cs # 生成 NarakaApiClient DTOClient 模式 │ └── HttpApiTestSourceGenerator.cs # 生成 HTTP API 测试代码Tests 模式 │ ├── BlackGoldAncientSword.Modules/ # UI 页面模块10 个 Prism IModule │ ├── Mappings/BattleMappingRegister.cs # Mapster 映射注册 │ ├── Module/ # 10 个 IModule 注册 │ │ ├── AnnouncementModule.cs # 公告 │ │ ├── BattleDetailModule.cs # 对局详情浮层personal/team/top5 三 Tab │ │ ├── ClosePromptModule.cs # 关闭确认弹窗 │ │ ├── FeedbackModule.cs # 意见反馈 │ │ ├── HomeModule.cs # 首页游戏状态监控 │ │ ├── SearchModule.cs # 搜索历史 │ │ ├── SettingsModule.cs # 设置 │ │ ├── StatsModule.cs # 战绩查询 │ │ ├── TeamInfoModule.cs # 队伍信息OCR 对比 │ │ └── UpdateNotificationModule.cs # 新版本提示 / 启动更新器 │ └── UI/ # 各模块的 ViewModels Views │ ├── BattleDetail/ # 对局详情并行拉 personal/team/top5 │ ├── Stats/Services/ # 战绩聚合服务 │ ├── TeamInfo/Services/ # TeamInfoOcrService、TeamOcrCoordinator │ └── UpdateNotification/ViewModels/ # 拉起 BlackGoldAncientSword.Update.exe │ ├── BlackGoldAncientSword.GameMonitor/ # 游戏监控 │ ├── Models/ # BattleEventArgs、PlayerPrefsData │ ├── Services/ │ │ ├── Abstractions/ # IGameLogMonitor / IGameStatusMonitor / IPlayerPrefsService │ │ └── Implementation/ │ │ ├── GameLogMonitor.cs # facade编排生命周期与事件分发 │ │ ├── GameStatusMonitor.cs # 游戏状态状态机 │ │ ├── PlayerPrefsService.cs # 本地用户偏好 │ │ └── Internal/ │ │ ├── BattleStateMachine.cs # 战局状态机 │ │ ├── LogPoller.cs # 轮询循环 │ │ └── LogReader.cs # Player.log 读取 │ └── GameMonitorAutoRegister.cs # 服务自动注册 │ ├── BlackGoldAncientSword.ScreenCapture/ # 屏幕捕获Windows Graphics Capture API │ ├── IScreenCaptureService.cs # 服务接口 │ ├── ScreenCaptureService.cs # WGC 封装 │ ├── NativeWgc.cs / WgcInterop.cs # 原生 WGC API 互操作 │ ├── ScreenQuadrant.cs # 屏幕四象限分割 │ ├── native/ # 原生 C 源码与构建脚本 │ └── runtimes/win-x64/native/ │ └── wgc_capture.dll # 原生 C/WinRT 捕获库 │ ├── BlackGoldAncientSword.Ocr/ # OCR 引擎进程内 ONNX Runtime │ ├── IOcrService.cs # 服务接口 │ ├── OcrEngine.cs # RapidOcrNetPP-OCRv5封装 │ └── OcrAutoRegister.cs # 服务自动注册 │ ├── BlackGoldAncientSword.Resources/ # 多语言资源 │ ├── Images/ # UI 图片、应用图标 (app.ico) │ └── Themes/ │ ├── Strings.zh-CN.xaml # 简体中文 │ ├── Strings.en.xaml # English │ └── Strings.zh-TW.xaml # 繁體中文 │ └── BlackGoldAncientSword.Tests/ # 测试项目xUnit Moq ├── GameMonitor/ # 游戏监控测试 ├── Http/ # HTTP / JSON 容错测试部分代码由源码生成器产出 ├── Ocr/ # OCR 测试 ├── ScreenCapture/ # 屏幕捕获测试 ├── Update/ # 更新流程测试 └── TestData/ # 测试数据 ocr_engine/ # PP-OCRv5 ONNX 模型与字典被 Ocr 项目拷贝至输出目录 └── models/v5/ # PP-OCRv5 中文 mobile 模型 (~22MB) ├── ch_PP-OCRv5_det_mobile.onnx # 文本检测 DBNet ├── ch_PP-LCNet_x0_25_textline_ori_cls_mobile.onnx # 方向分类 ├── ch_PP-OCRv5_rec_mobile.onnx # 字符识别 CRNN └── ppocrv5_dict.txt # 字典18383 字符覆盖中/英/日/拉丁扩展等Framework 服务接口一览BlackGoldAncientSword.Framework/Services/Abstractions/下共 13 个公开接口接口主要实现用途IAppAssemblyMarkerAppAssemblyMarker程序集定位标记XAML 资源解析IApplicationLifetimeWpfApplicationLifetime退出 / 重启应用IClipboardServiceWpfClipboardService剪贴板读写IGiteeReleaseServiceGiteeReleaseService拉取 Gitee Releases 列表与资产含 302 tag 探测 CDN 分卷 HEAD 探测零 API 依赖IImageCacheServiceImageCacheService图片磁盘缓存ILocalizationServiceLocalizationService动态切换语言重载 XAML 资源字典ILocalizedTextProviderWpfLocalizedTextProvider代码侧读取本地化字符串ISearchHistoryServiceSearchHistoryService搜索历史持久化ISettingsServiceSettingsService应用配置读写ITeamOverlayServiceTeamOverlayService英雄选择时的右下角队伍弹窗ITipMessageServiceTipMessageService全局 Toast / 提示消息IUIDispatcherWpfUIDispatcher跨线程 UI 调度封装IUpdateServiceUpdateService比对版本、解析最新 Gitee release 的 Setup / zip / 分卷 URL走 302 CDN避 API rate limitGameMonitor、Ocr、ScreenCapture各自暴露自身的接口IGameLogMonitor/IGameStatusMonitor/IPlayerPrefsService、IOcrService、IScreenCaptureService通过各模块的*AutoRegister.cs注册到 DI 容器。核心模块说明1. MVVM 架构Prism DryIoc所有 ViewModel 继承自ViewModelBase提供RaisePropertyChanged()方法遵循 CLAUDE.md / AGENTS.md 规范禁止SetProperty封装属性变更通知使用nameof()或[CallerMemberName]禁止硬编码属性名字符串ViewModel 中禁止引用 WPF 类型Visibility、Brush、Color等可见性用bool Converter 表达页面通过IMainContentNavigationService进行导航支持前进 / 后退跨模块通信使用IEventAggregator发布 / 订阅事件如TipMessageEvent、SettingsChangedEvent2. 模块化按需加载9 个 UI 页面分别是一个 PrismIModule在ModuleCatalogConfigManager中配置为OnDemand首次导航到某页面时才加载对应模块减少启动时间。// PageNames.cspublicstaticclassPageNames{publicconststringHomePagenameof(HomePage);publicconststringStatsPagenameof(StatsPage);publicconststringSearchPagenameof(SearchPage);publicconststringTeamInfoPagenameof(TeamInfoPage);publicconststringSettingsPagenameof(SettingsPage);publicconststringAnnouncementPagenameof(AnnouncementPage);publicconststringClosePromptPagenameof(ClosePromptPage);publicconststringFeedbackPagenameof(FeedbackPage);publicconststringUpdateNotificationPagenameof(UpdateNotificationPage);publicconststringBattleDetailPagenameof(BattleDetailPage);}3. 游戏状态监控GameMonitorGameLogMonitor采用FileSystemWatcher 定时轮询双保险监听 Player.log 文件变更。内部将职责拆分为LogReader文件读取LogPoller轮询循环BattleStateMachine战局状态机外层GameLogMonitor仅作为 facade 编排生命周期与事件分发。监测到的事件BattleJoined— 进入英雄选择解析日志中的 RoomIdBattleStarted— 对局开始解析 BattleIdBattleEnded— 对局结束GameStatusMonitor维护游戏状态机通知各页面当前处于哪个阶段HeroSelection/InGame/BattleEnded。HomePageViewModel额外使用Process.GetProcessesByName(NarakaBladepoint)检测进程是否存在作为辅助判断。4. 屏幕捕获与 OCR队伍信息识别队伍信息识别流程GameStatusMonitor检测到HeroSelection状态TeamInfoPageViewModel启动 OCR 轮询循环ScreenCaptureService通过Windows Graphics Capture API原生 C/WinRT DLL → SharpDX D3D11截取游戏窗口使用ArrayPool复用全帧缓冲按ScreenQuadrant切出三个 region 拼图OcrEngine基于RapidOcrNet ONNX Runtime 进程内推理byte[] → SkiaSharp 解码为SKBitmap→ 单次Detect()串联跑 detDBNet→ cls方向分类可关→ recCRNN三段 ONNX 推理。模型 字典首次调用PrewarmAsync时加载约 200500 ms并跑一次最小推理触发 ONNX session 内部 buffer 与 kernel 编译。SemaphoreSlim串行化保护 RapidOcr 内部状态无子进程 / 无 IPC / 无 JobObject 兜底TeamInfoOcrService/TeamOcrCoordinator解析 OCR 结果提取队友昵称调用战绩 API 查询每个队友的数据并排展示5. HTTP API 源码生成API 客户端不手写而是通过BlackGoldAncientSword.Framework.SourceGenerator在编译期从Http/Definitions/*.json自动生成JSON 定义文件描述 API 的端点、请求 / 响应数据结构与枚举生成器以Roslyn Source Generator形式工作被 Framework / Tests 两端以 Analyzer 引用通过BgaSourceGenMode属性切换产物Client模式Framework— 生成NarakaApiClient DTOTests模式Tests— 生成 HTTP API 测试代码6. 多语言支持多语言通过 WPFResourceDictionary实现所有 UI 文本定义在Strings.{zh-CN,en,zh-TW}.xaml中。运行时通过ILocalizationService.ApplyLanguage()动态切换资源字典无需重启。7. 在线更新独立 Updater 进程更新由两端协作完成主程序侧Modules/UI/UpdateNotification/ViewModels/UpdateNotificationPageViewModel.cs通过IUpdateService走 Gitee release 网页 302 提取 tag CDN HEAD 探测分卷检测新版本用户点击在线更新后启动同目录下的BlackGoldAncientSword.Update.exe传入--url zip 下载地址、--target 安装目录、--main-exe BlackGoldAncientSword.App.exe无网 / GitHub 被墙用户可从 Gitee Release 页面下载BlackGoldAncientSword-win-x64-Downloader.exe离线下载器双击后自动流式拉取分卷安装包并调起 Setup更新器侧BlackGoldAncientSword.Update独立进程不引用任何业务项目仅依赖 HandyControl避免 DLL 被锁定影响整目录覆盖UpdaterRunner编排下载 zip0–90%→ 解压90–98%→ 提示关闭主程序 → 全量覆盖 → 重新拉起主程序 → 自身退出以 self-contained PublishSingleFileEnableCompressionInSingleFile发布构建与运行环境要求Windows 10/11 x64.NET 10.0 SDKPowerShell 7推荐UTF-8 环境构建命令# 还原 编译整个解决方案dotnet build src/BlackGoldAncientSword.slnx# 仅编译主程序dotnet build src/BlackGoldAncientSword.App/BlackGoldAncientSword.App.csproj-c Debug# Release 发布主程序自包含单文件 exedotnet publish src/BlackGoldAncientSword.App/BlackGoldAncientSword.App.csproj-c Release-o publish/App# Release 发布更新器自包含单文件 exe需与主程序放同目录dotnet publish src/BlackGoldAncientSword.Update/BlackGoldAncientSword.Update.csproj-c Release-o publish/Updater# Release 发布离线下载器自包含单文件 exe作为 Release 独立附件发布不进主程序安装目录dotnet publish src/BlackGoldAncientSword.Downloader/BlackGoldAncientSword.Downloader.csproj-c Release-o publish/Downloader项目约定对代码做任何修改后必须运行dotnet build src/BlackGoldAncientSword.slnx0 error 才算完成。运行测试dotnet test src/BlackGoldAncientSword.Tests/BlackGoldAncientSword.Tests.csprojCI / 发布流程.github/workflows/下共两个工作流工作流触发用途main-build.ymlpush / PR →main校验性构建dotnet build src/BlackGoldAncientSword.slnx不发布dotnet-desktop.ymlpush →release完整发版版本号自增 → 编译 App → 发布 App Updater Downloader自包含单文件→ 打包 zip Inno Setup 全量 / 分卷安装包 → 创建 GitHub Release发版流程要点从已有 git tagsv*.*.*.*形式推断版本号并自增 build 段修改App.csproj的Version/AssemblyVersion/FileVersion分别发布 App、Update、Downloader 为自包含单文件 .exe合并 build publish 输出并把 Updater exe 一并塞进安装目录 → 压缩为BlackGoldAncientSword-v{version}.zip 7z 分卷-split.zip.NNN≤99MB / 卷用setup.issInno Setup 脚本分别生成全量安装包BlackGoldAncientSword-{version}-win-x64-Setup.exe与 DiskSpanning 分卷安装包-Split.exe.bin额外产出两份无版本号别名BlackGoldAncientSword-win-x64-Setup.exe/-Downloader.exe配合/releases/latest/download/magic redirect 提供永久指向最新版的分享链接创建 GitHub Release自动列举上一版本到本次的 commit 标题release分支已开启分支保护禁直推 / 禁 force-push / 禁删除且对管理员同样生效enforce_admins所有变更必须通过 PR 合并进来。日常开发在main分支进行发版时先由 git-commit skill commit pushmain随后在 GitHub 上创建main→release的 PR 并合并由此触发dotnet-desktop.yml完成发版。许可证本项目基于 MIT License 开源。作者小窗同学。