☰
Windows 自更新难题怎么破:CircuitLordVRModInstaller 的 rename-swap 自更新实现教程
2026/10/14 18:12:39 网站建设 项目流程

【免费下载链接】CircuitLordVRModInstaller

One-click installer for Big Walk VR and Titanfall 2 VR

项目地址:https://gitcode.com/gh_mirrors/ci/CircuitLordVRModInstaller
点击查看免费下载

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.jsoninstaller字段声明最新版本号、下载地址与 SHA-256
版本比较Models.csVersionUtil.IsNewer支持beta等预发布版本号的语义化比较
更新入口MainWindow.xaml.cs检测到新版本后显示"Installer update available"横幅与 Update now 按钮

值得留意的是 manifest 的"版本冻结"设计:仓库同时保留 manifest.json 和 manifest-v2.json 等旧版 manifest,老版本安装器仍能找到对应的新版自己完成升级,保证升级链路不断档。

如何在你自己的项目里复用这套方案

如果你也在做 Windows 桌面应用,这套 rename-swap 模式可以直接借鉴,检查清单如下:

  1. 下载后必做哈希校验:先验证 SHA-256 再动文件,把风险隔离在写入之前
  2. 改名前先清理残留:删除上次更新遗留的.old.exe,避免脏状态
  3. 写入包在 try/catch 中:失败立即回滚改名,保证程序可用性
  4. 换装完成立即启动新进程:不要在旧进程里做任何收尾逻辑
  5. 启动时兜底清理:带重试地删除旧文件句柄可能锁定的.old.exe
  6. 用 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

项目地址:https://gitcode.com/gh_mirrors/ci/CircuitLordVRModInstaller
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询