# Мы написали свой установщик, и NeuroSquad теперь обновляется сам

> Почему NeuroSquad заменил сгенерированный установщик своим: 550 МБ превратились в 96, мешающие процессы названы по PID, а обновление не оставляет недоустановленное приложение.

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

NeuroSquad 0.1.100 — первая версия, которая сама следит за своей актуальностью. Путь сюда занял три выпуска меньше чем за сутки и дал самый полезный урок недели: установщик — часть продукта. Это первое окно, которое видят люди, и когда он ломается, он ломается в худшем месте — между старой версией, которой уже нет, и новой, которой ещё нет.

## С 550 МБ до 96

Первый публичный установщик весил 550 МБ. Большую часть занимала модель диктовки — около 640 МБ в распакованном виде; её положили внутрь, чтобы голосовой ввод работал сразу после запуска. Но диктовка — вещь необязательная, и заставлять всех качать её ради того, чтобы попробовать холст с агентами, было неудачным компромиссом.

В 0.1.92 модель из установщика убрали. Теперь она скачивается, когда вы её попросите, — на шаге «Диктовка» мастера настройки или позже в настройках, — а диктовка включается сама, как только загрузка закончится, без перезапуска. До тех пор строка состояния пишет «Диктовка: скачайте модель», а не показывает ошибку. Установщик похудел примерно до 110 МБ.

Остальное нашлось в менее эффектном месте — в том, что упаковывается. Упаковщик целиком копирует каждую рабочую зависимость приложения, а десктопное приложение перечисляло там весь стек интерфейса — библиотеки компонентов, наборы иконок, инструментарий доступности, — хотя сборщик и так вкомпилирует всё это в страницу. Перенос всего, что нужно только странице, из рантайм-зависимостей сэкономил около 70 МБ файлов, которые никто никогда не загружал. 0.1.94 вышел на 96 МБ.

- **550 МБ** — первый публичный установщик, 0.1.91
- **110 МБ** — без модели диктовки, 0.1.92
- **96 МБ** — только то, что приложение загружает при работе, 0.1.94

> **Крюк через 1,7 ГБ** Один эксперимент раздул установщик до 1,7 ГБ. Список файлов, объявленный только для Windows, не дополняет общий список, а заменяет его — и сборка упаковала всё, что лежало в папке. Теперь это записанное правило сборки.

## Почему сгенерированному установщику пришлось уйти

Первые установщики генерировал инструмент упаковки, и два бага в них были настолько неприятными, что оправдали написание собственного.

Первый: он отказывался ставиться с сообщением «NeuroSquad не может быть закрыт», хотя NeuroSquad уже был закрыт. Проверка звучала как «запущен ли хоть какой-то процесс из папки установки» — без имён. А запущенными оставались консольные хосты терминалов из карточек агентов, пережившие выход из приложения. Их не было видно, сообщение их не называло, и нажать было не на что.

Второй был хуже: прерванная установка могла оставить после себя недописанное приложение. В одном случае это был `neurosquad.exe` на 8 МБ вместо 200 — и никакой записи в списке приложений Windows, через которую его можно было бы удалить.

## Новый установщик

Это небольшая WPF-программа для .NET Framework 4.8, который уже входит в Windows 10 и 11, так что заранее ничего ставить не нужно. Сам исполняемый файл весит около 240 КБ; приложение дописано к нему LZMA-архивом, нарезанным на блоки по 32 МБ, которые упаковываются и распаковываются параллельно, с CRC-32 для каждого файла. Сборка один раз скачивает свой компилятор C# и сверяет его с закреплённым SHA-256; SDK на машине сборки тоже не нужен.

![Первая страница установщика: папка установки и ярлык на рабочем столе](https://neurosquad.ai/blog/own-installer-and-auto-updates/installer-welcome-ru.webp)

*Выберите папку — для папки по умолчанию права администратора не нужны — и нужен ли ярлык на рабочем столе. Установщик говорит по-английски, по-русски и по-китайски.*

Отличается он в основном тем, что говорит вам правду:

- **Живой журнал каждого шага** — в окне и в файле в `%TEMP%`, так что у любого сбоя есть строка, на которую можно показать пальцем.
- **Мешающие процессы перечислены по имени и PID** и завершаются только по нажатию кнопки. Никаких догадок и тихих убийств.
- **Обновление никогда не пишет поверх.** Новая версия распаковывается рядом со старой, проверяется, и папки меняются местами, только когда всё на месте. Сбой или отмена оставляют старую версию ровно такой, какой она была.
- **Удаление убирает то, что было установлено**, — файлы из списка, составленного при установке, ярлыки и запись в «Приложениях». Ваши данные удаляются, только если вы поставите галочку.

![Установщик показывает, что держит папку установки: neurosquad.exe и OpenConsole.exe с их PID](https://neurosquad.ai/blog/own-installer-and-auto-updates/installer-processes-ru.webp)

*Что держит папку — по имени и PID: само приложение и терминалы его карточек. Завершаются, только когда вы нажмёте кнопку.*

![Установка не смогла заменить файл: ошибка, журнал и пометка, что прежняя версия на месте](https://neurosquad.ai/blog/own-installer-and-auto-updates/installer-failed-ru.webp)

*Если файл всё равно не заменить, установка останавливается с открытым журналом, а прежняя версия остаётся как была.*

Одна деталь невидима и при этом обязательна: ярлык в меню «Пуск» должен нести AppUserModelID приложения. Без него Windows не доставляет всплывающие уведомления приложения — а «ваш агент ждёт вас» и есть то уведомление, вокруг которого построен весь продукт.

Проверять установщик на машине, где ведётся разработка, рискованно, поэтому у него есть два ключа как раз для этого. `--snapshot` сохраняет каждую страницу в PNG на любом из трёх языков. `--sandbox` кладёт ярлыки и запись «Приложений» в папку вместо меню «Пуск» и реестра, так что установку, обновление и удаление можно прогнать от начала до конца, не трогая систему.

## Обновления, которые ставятся сами

Когда установщик умеет безопасно заменить работающую копию, автообновление становится возможным. NeuroSquad проверяет новый выпуск при каждом запуске и раз в час, скачивает его в фоне и сверяет SHA-256 с контрольной суммой, которую публикует сам выпуск. Нет контрольной суммы — нет установки.

Обновления не отключаются; выбираете вы только время. Кольцо в заголовке окна показывает загрузку, затем значок с точкой позволяет обновиться в любой момент, а диалог один раз на версию спрашивает: сейчас или при следующем запуске. «Сейчас» закрывает приложение и передаёт работу установщику, который дожидается выхода приложения, ставит новую версию поверх и запускает её. Следующий запуск ставит известную более новую версию ещё до открытия приложения — а если сети нет, после трёх попыток сдаётся и открывает ту версию, что есть.

*Копия заголовка окна и диалога обновления со строками самого приложения. Выберите «Обновить сейчас» или «При следующем запуске».* (interactive: https://neurosquad.ai/ru/blog/own-installer-and-auto-updates/)

## Баг, который нашла проверка обновления

Обновление проверяли по-настоящему: две сборки, локальная лента выпусков, обновление при запуске, обновление посреди работы приложения и запуск без сети с уже скачанным обновлением. С «Обновить сейчас» новая версия появлялась на экране примерно через десять секунд.

А до этого первый прогон упал — на обмене папок. Что-то всё ещё держало папку установки, и это было не приложение. Это был тот же осиротевший консольный хост, что сбивал с толку старый установщик: дочерний процесс терминала карточки, у которого *рабочей папкой* была папка установки — потому что оттуда было запущено само приложение. Процесса, для которого папка является текущей, достаточно, чтобы Windows не дала её переименовать.

Исправление — одна строка в самом начале запуска приложения: сменить рабочую папку на домашнюю. Дочерние процессы её наследуют, и папка установки больше ни для кого не текущая. Вторую половину закрыл 0.1.108: при обновлении со старой версии, чьи оставшиеся терминалы всё ещё держат папку, установщик теперь показывает их вместе с остальными процессами, а если файл держит что-то, что он не может опознать, — например, окно Проводника, — он не сдаётся, а заменяет файлы по одному и возвращает всё как было, если какой-то шаг не удался.

> Установщик — единственная часть приложения, которую нельзя исправить следующим обновлением. Он должен работать правильно, пока ничего другого не запущено.

Если у вас 0.1.94 или старше, один раз запустите новый установщик поверх — дальше обновления будут приходить сами. Всё, что изменилось, — в [журнале изменений 0.1.100](https://neurosquad.ai/ru/changelog/#v0.1.100).
