# 我们自己写了安装程序，NeuroSquad 从此会自动更新

> NeuroSquad 为什么用自研安装程序替换自动生成的那个：安装包从 550 MB 减到 96 MB，挡路的进程按名称和 PID 列出，更新绝不会留下装了一半的应用。

- URL: https://neurosquad.ai/zh/blog/own-installer-and-auto-updates/
- Published: 2026-09-24
- Publisher: NeuroSquad (https://neurosquad.ai/)

NeuroSquad 0.1.100 是第一个能自己保持最新的版本。走到这一步，用了不到一天、连发三个版本，也得到了这周最有用的一条教训：安装程序是产品的一部分。它是用户看到的第一个窗口，而它一旦失败，就败在最糟糕的位置——旧版本已经没了，新版本还没到。

## 从 550 MB 到 96 MB

第一个公开的安装程序有 550 MB。大头是听写模型：解压后约 640 MB，打包进来是为了让语音输入在应用打开的那一刻就能用。可听写是可选功能，为了试一块智能体画布就让所有人把它下载下来，这笔账算错了。

0.1.92 不再打包它。模型改为在你需要时下载——在设置向导的“听写”步骤，或之后在“设置”里——下载一完成，听写就自动启用，无需重启。在此之前，状态栏会显示“听写：请下载模型”，而不是报错。安装程序降到了约 110 MB。

剩下的瘦身来自一个不那么光鲜的地方：到底打包了什么。打包工具会把应用的每一个生产依赖完整复制进去，而桌面应用把整套界面技术栈都列在了那里——组件库、图标集、无障碍工具包——尽管打包器早已把这些编译进了页面。把只有页面才需要的东西移出运行时依赖后，省下了约 70 MB 从来没有被加载过的文件。0.1.94 发布时是 96 MB。

- **550 MB** — 首个公开安装程序，0.1.91
- **110 MB** — 去掉听写模型，0.1.92
- **96 MB** — 只保留应用运行时加载的内容，0.1.94

> **1.7 GB 的弯路** 有一次试验让安装程序膨胀到了 1.7 GB。只为 Windows 声明的文件列表不会追加到通用列表上——而是直接替换它——于是构建把文件夹里的一切都打了进去。现在这已是构建的一条成文规则。

## 为什么自动生成的安装程序必须下岗

最初的安装程序由打包工具生成，其中有两个问题严重到足以让我们自己动手重写。

第一个：NeuroSquad 明明已经关了，它却提示“NeuroSquad 无法关闭”并拒绝安装。它的检查逻辑是“有没有任何进程从安装文件夹里运行”，而且不报名字。真正在运行的，是智能体卡片里那些终端的控制台宿主进程，应用退出后被遗留了下来。你看不到它们，提示里也不点名，也没有任何可以点的按钮。

第二个更糟：被中断的安装可能留下一个写了一半的应用。有一次的情况是：`neurosquad.exe` 只有 8 MB（本该是 200 MB），而且 Windows 的应用列表里也没有它的条目，连卸载都无从下手。

## 新的安装程序

它是一个小巧的 WPF 程序，基于 Windows 10 和 11 自带的 .NET Framework 4.8，所以无需预先安装任何东西。可执行文件本身约 240 KB；应用作为 LZMA 负载附加在它后面，切成 32 MB 的块并行压缩和解压，每个文件都有 CRC-32 校验。构建时只下载一次 C# 编译器，并用固定的 SHA-256 校验；构建机器上同样不需要任何 SDK。

![安装程序的第一页：安装文件夹和桌面快捷方式](https://neurosquad.ai/blog/own-installer-and-auto-updates/installer-welcome-zh.webp)

*选择文件夹——默认位置不需要管理员权限——以及是否创建桌面快捷方式。安装程序支持英语、俄语和中文。*

它的不同之处，主要在于对你说实话：

- **每一步都有实时日志**，既显示在窗口里，也写进 `%TEMP%` 下的文件，出了问题总有一行字可以指给人看。
- **挡路的进程按名称和 PID 列出**，只有在你按下按钮后才会结束它们。不靠猜，也不悄悄强杀。
- **更新从不原地覆盖。**新版本解压到旧版本旁边，校验通过、一切就绪后才交换两个文件夹。失败或取消都会让旧版本原封不动。
- **卸载只删除装进来的东西**——安装时记录的文件、快捷方式和“应用”列表中的条目。你的数据只有在勾选后才会删除。

![安装程序列出占用安装文件夹的进程：neurosquad.exe 和 OpenConsole.exe 及其 PID](https://neurosquad.ai/blog/own-installer-and-auto-updates/installer-processes-zh.webp)

*占用文件夹的是什么，按名称和 PID 列出——应用本身和它卡片里的终端——只有你按下按钮才会结束它们。*

![安装无法替换某个文件：显示错误、日志，并注明原来的版本仍然保留](https://neurosquad.ai/blog/own-installer-and-auto-updates/installer-failed-zh.webp)

*如果某个文件仍然无法替换，安装会停下并打开日志，你原来的版本保持原样。*

有一个细节看不见，却至关重要：“开始”菜单快捷方式必须带有应用的 AppUserModelID。没有它，Windows 就不会投递应用的通知——而“你的智能体在等你”恰恰是整个产品赖以成立的那条通知。

在开发用的机器上测试安装程序是有风险的，所以它为此准备了两个开关。`--snapshot` 会把每一页渲染成 PNG，三种语言任选。`--sandbox` 会把快捷方式和“应用”列表条目放进一个文件夹，而不是写进“开始”菜单和注册表，这样安装、更新和卸载都能完整跑一遍，而不碰系统分毫。

## 会自己安装的更新

有了能安全替换正在运行的副本的安装程序，自动更新才成为可能。NeuroSquad 每次启动时和之后每小时检查一次新版本，在后台下载，并用发布页自己公布的校验和核对 SHA-256。没有校验和，就不安装。

更新不是可选项；你能选的是时机。标题栏里的一个圆环显示下载进度；下载完成后，一个带小圆点的图标让你随时可以更新，另有一个对话框对每个版本只问一次：现在，还是下次启动时。选“现在”，应用会关闭并把工作交给安装程序，安装程序等应用退出后覆盖安装，再启动新版本。下次启动时，如果已知有更新的版本，会在应用打开之前就先装好——如果你处于离线状态，应用尝试三次后放弃，打开你现有的版本。

*标题栏和更新对话框的复刻，用的是应用自己的文字。选“立即更新”或“下次启动时”试试。* (interactive: https://neurosquad.ai/zh/blog/own-installer-and-auto-updates/)

## 更新测试揪出来的那个 bug

更新流程是实打实测过的：两个构建、一个本地发布源，分别测试启动时更新、应用工作中更新，以及离线状态下用已下载好的更新启动。选“立即更新”后，大约十秒钟新版本就出现在屏幕上。

在那之前，第一次运行失败了——卡在交换文件夹这一步。有东西仍然占着安装文件夹，而且不是应用本身。还是那个曾让旧安装程序犯迷糊的孤儿控制台宿主进程：它是某张卡片终端的子进程，它的*工作目录*就是安装文件夹，因为应用本身就是从那里启动的。一个进程只要把某个文件夹当作当前目录，就足以让 Windows 无法重命名它。

修复只有一行，放在应用启动的最开头：把工作目录切换到用户主文件夹。子进程会继承它，安装文件夹也就不再是任何进程的当前目录。0.1.108 补上了另一半：从旧版本更新时，如果旧版本遗留的终端仍占着文件夹，安装程序现在会把它们和其他进程一起列出来；如果还有它识别不出的东西占着某个文件——比如一个资源管理器窗口——它会逐个替换文件而不是直接放弃，并且任何一步失败都会把一切恢复原样。

> 安装程序是应用里唯一一个无法靠下一次更新来修复的部分。它必须在其他一切都没运行的时候做对。

如果你用的是 0.1.94 或更早的版本，请在其上运行一次新的安装程序；之后更新都会自动到来。所有变化见 [0.1.100 的更新日志](https://neurosquad.ai/zh/changelog/#v0.1.100)。
