【免费下载链接】CircuitLordVRModInstaller
One-click installer for Big Walk VR and Titanfall 2 VR
CircuitLordVRModInstaller 是一款一键安装 Big Walk VR 和 Titanfall 2 VR 模组的一体化工具,它内置了一套非常实用的 Windows 自更新机制:程序能在自己保持运行的状态下完成 exe 文件的替换与重启。本文拆解它采用的 rename-swap 自更新方案,讲清楚为什么 Windows 上"替换正在运行的 exe"这么难,以及这套方案如何用 4 步 + 回滚 + 清理把问题彻底解决。
为什么 Windows 程序很难"更新自己"
在 Windows 上,一个正在运行的 .exe 文件被系统锁定:
- ✅可以改名(rename)
- ❌不能被覆盖或删除(overwrite / delete)
这意味着程序无法直接用自己的新安装包覆盖自身文件——这是几乎所有桌面应用自更新遇到的头号难题。常见的解法有第三方更新器、UAC 提权重启、计划任务延迟替换等,但实现都偏重。
CircuitLordVRModInstaller 选择了一个更巧妙的思路:既然不能覆盖,那就先把旧文件"让开"。这个思路被称为rename-swap(改名换装):把正在运行的 exe 改名为.old.exe,腾出原路径后写入新版本,再启动新进程,旧文件等下次启动时清理。
rename-swap 四步换装:核心流程拆解
核心实现集中在 SelfUpdater.cs,其中ApplyUpdate方法(L43-L60)只有短短十几行,流程如下:
第 1 步:下载新版 exe 并校验完整性
新版本从 manifest 中声明的 URL 下载,下载完成后用 SHA-256 逐字节比对,防止网络传输损坏或内容被篡改。下载逻辑复用自 RepoClient.cs 的Download方法,同时支持进度回调,界面可以实时显示下载进度。
第 2 步:把旧 exe 改名让位
先删除上一次更新可能残留的.old.exe,然后把当前正在运行的 exe 改名为CircuitLordVRModInstaller.old.exe。这一步利用了"运行中的 exe 可以改名"的 Windows 特性。
第 3 步:把新版本写入原路径
原路径此时已经空闲,直接把下载好的新 exe 写入原路径。至此,"换装"完成。
第 4 步:启动新进程,旧进程退出
启动刚写入的新版本 exe,随后旧进程调用Application.Current.Shutdown()安静退出(见 MainWindow.xaml.cs 中的SelfUpdate_Click)。用户视角只是窗口闪了一下,程序已经"焕然一新"。
两个关键细节:失败回滚与残留清理
rename-swap 真正值得学习的地方,在于它把"出错了怎么办"考虑得滴水不漏。🛡️
写新文件失败?立即回滚
第 3 步写入新 exe 如果失败(比如磁盘空间不足),代码会立刻执行File.Move(old, exe),把旧文件改回原名,保证用户手里的程序始终是完整的可用版本,绝不会留下一个半新半旧的目录。
旧进程还占着 .old.exe?耐心重试删除
旧进程退出前,.old.exe可能被其残留句柄占用导致删除失败。程序在每次启动时执行 CleanupOldExe:最多重试 12 次、每次间隔 500 毫秒,直到删掉这个残留文件。调用点在 App.xaml.cs 的启动入口——这意味着即使某次更新后用户直接关闭了程序,下次打开也会自动收拾干净。
更新怎么被发现:版本判断与 UI 入口
自更新不是无脑触发,整套机制由三部分组成:
| 环节 | 实现位置 | 说明 |
|---|---|---|
| 版本来源 | manifest-v3.json | installer字段声明最新版本号、下载地址与 SHA-256 |
| 版本比较 | Models.cs | VersionUtil.IsNewer支持beta等预发布版本号的语义化比较 |
| 更新入口 | MainWindow.xaml.cs | 检测到新版本后显示"Installer update available"横幅与 Update now 按钮 |
值得留意的是 manifest 的"版本冻结"设计:仓库同时保留 manifest.json 和 manifest-v2.json 等旧版 manifest,老版本安装器仍能找到对应的新版自己完成升级,保证升级链路不断档。
如何在你自己的项目里复用这套方案
如果你也在做 Windows 桌面应用,这套 rename-swap 模式可以直接借鉴,检查清单如下:
- 下载后必做哈希校验:先验证 SHA-256 再动文件,把风险隔离在写入之前
- 改名前先清理残留:删除上次更新遗留的
.old.exe,避免脏状态 - 写入包在 try/catch 中:失败立即回滚改名,保证程序可用性
- 换装完成立即启动新进程:不要在旧进程里做任何收尾逻辑
- 启动时兜底清理:带重试地删除旧文件句柄可能锁定的
.old.exe - 用 manifest 而非硬编码管理版本:版本号、URL、哈希集中声明,还能保留旧 schema 兼容老用户
整套实现不到 60 行代码,无第三方依赖,是"小而完整"的工程范例。
总结
Windows 自更新的核心矛盾是"运行中的 exe 无法被覆盖",CircuitLordVRModInstaller 用 rename-swap 三步曲给出了教科书式答案:改名让位 → 写入新版 → 重启切换,再用失败回滚和启动清理兜住所有异常路径。对新手来说,SelfUpdater.cs 是一份极佳的阅读材料——短小、完整、每一行都有注释说明"为什么",强烈建议配合 RepoClient.cs 一起学习。
【免费下载链接】CircuitLordVRModInstaller
One-click installer for Big Walk VR and Titanfall 2 VR
相关推荐
AIRI 怎么检查自动更新:更新通道选择、手动检查更新与 Updater 查看更新源
AIRI 怎么检查自动更新:更新通道选择、手动检查更新与 Updater 查看更新源 在 AIRI 桌面版上,你可能需要三件事:确认当前是不是最新版本、给自动更
AI 应用人工智能大模型数字人AI Agent语音前端后端桌面应用移动开发即时通讯3D渲染Ghost Downloader 3 自动更新系统:Patch 增量更新 + C 语言 Updater 是怎么做的
Ghost Downloader 3 自动更新系统:Patch 增量更新 + C 语言 Updater 是怎么做的 ! Ghost Downloader 3 项
桌面应用网络插件系统PowerToys 自动更新被 GPO 或设置禁用怎么排查?
PowerToys 自动更新被 GPO 或设置禁用怎么排查? PowerToys 更新机制的工作流程是:先通过 GitHub API 检测最新版本,发现新版本后
桌面应用开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考