Перейти к содержимому

Установщик Windows для приложения .NET (WPF, WinForms, консоль)

Опубликуйте настольное приложение .NET через dotnet publish, выберите между framework-dependent и self-contained и упакуйте папку публикации в Setup.exe с ярлыками и деинсталлятором.

Обновлено 31 октября 2026 г. · 3 мин чтения

Visual Studio собирает ваше приложение WPF или WinForms, а dotnet publish выдаёт папку, которая запускается где угодно. Не хватает только установщика: пункта в меню «Пуск», папки в Program Files, записи об удалении в параметрах Windows. Старые ClickOnce и Visual Studio Installer Projects никуда не делись, но оба заметно устарели. Вот самый прямой путь от проекта .NET к Setup.exe.

Шаг 1: опубликуйте приложение

Публикация создаёт папку со всем, что нужно приложению. Запустите команду из папки проекта:

dotnet publish -c Release -r win-x64 --self-contained true

Результат окажется в bin\Release\net8.0-windows\win-x64\publish\ (целевой фреймворк в пути зависит от вашего проекта). Именно эту папку вы и распространяете.

Единственное решение, которое действительно важно:

  • Self-contained (--self-contained true) включает среду выполнения .NET в комплект. Папка весит от 70 до 150 МБ, зато запускается на любой машине с Windows без предварительной установки чего-либо. Выбирайте этот вариант для программ, которые распространяете публично.
  • Framework-dependent (--self-contained false) занимает несколько МБ, но у пользователя должна быть установлена подходящая .NET Desktop Runtime, иначе при первом запуске приложение покажет предложение её скачать. Подходит для внутренних инструментов на управляемых машинах.

Полезные параметры:

  • -p:PublishReadyToRun=true предварительно компилирует приложение для более быстрого запуска.
  • -p:PublishSingleFile=true сворачивает результат в один .exe. Это работает, но при наличии установщика смысл в нём пропадает, к тому же однофайловые приложения распаковывают нативные библиотеки при первом запуске. Обычная папка проще.
  • Обрезка (PublishTrimmed) не поддерживается для WPF и WinForms; оставьте её выключенной.

Задайте значок приложения в файле проекта, чтобы опубликованный .exe его содержал:

<PropertyGroup>
  <ApplicationIcon>app.ico</ApplicationIcon>
</PropertyGroup>

Запустите опубликованный .exe один раз из папки публикации, желательно на машине без Visual Studio, чтобы убедиться, что ничего не пропущено.

Шаг 2: запакуйте папку публикации в zip

Запакуйте содержимое publish`: .exe, DLL, .deps.json, .runtimeconfig.json и файлы контента, если есть. Файлы .pdb` не включайте, если только вам не нужны отладочные символы на машинах клиентов.

Шаг 3: соберите установщик

  1. Загрузите zip в ExeTup. Он выберет .exe вашего приложения как основную программу; проверьте выбор, поскольку self-contained-публикация содержит createdump.exe, а это не она.
  2. Укажите название, версию (держите её в соответствии с <Version> в проекте), издателя и лицензию.
  3. Выберите для всех пользователей для классического настольного приложения в Program Files или для текущего пользователя, если у клиентов может не быть прав администратора.
  4. Оставьте 64-бит для публикации win-x64; для win-x86 выберите 32-бит.
  5. Загрузите тот же app.ico, включите ярлыки и запустите сборку.

Скачайте Setup.exe и проверьте установку и удаление на Windows.

Особенности .NET

  • Обновления. Выпускайте новый установщик с более высокой версией. Установка поверх старой версии заменяет файлы; канала автообновления в установщике нет.
  • Настройки и данные. Записывайте пользовательские данные в %APPDATA% или %LOCALAPPDATA%, а не рядом с .exe. Program Files доступна обычным пользователям только для чтения, а деинсталлятор удаляет только то, что сам установил.
  • Зависимости. Self-contained-публикациям больше ничего не нужно. Если приложению требуется среда выполнения Visual C++ или драйвер базы данных, задокументируйте это; установщик не запускает другие установщики по цепочке.
  • Подпись кода. Подпишите опубликованный .exe перед упаковкой в zip, а затем подпишите скачанный Setup.exe. См. руководство по SmartScreen.

Альтернативы

  • Visual Studio Installer Projects создают MSI-файлы прямо из Visual Studio. По-прежнему доступны как расширение, ограничены и неудобны при работе с self-contained-публикациями.
  • ClickOnce даёт установку для текущего пользователя с автообновлением, привязанную к веб-серверу, который вы обслуживаете.
  • WiX Toolset собирает MSI-файлы из XML и является стандартом для MSI-упаковки корпоративного уровня. Мощный инструмент с соответствующей кривой обучения.
  • MSIX — более новый формат пакетов Microsoft, лучший выбор, если вы ориентируетесь на Microsoft Store.

Когда формат имеет значение, читайте в статье Установщики MSI и EXE.

Частые вопросы

Публиковать framework-dependent или self-contained?

Self-contained для всего, что вы отдаёте публике, чтобы приложение работало без скачивания среды выполнения. Framework-dependent для внутренних инструментов на машинах, где средой выполнения .NET управляет ИТ-отдел.

Включает ли установщик среду выполнения .NET?

Если вы публикуете self-contained, то да, поскольку она входит в папку публикации. Установщик поставляет всё, что находится в zip.

Можно ли получить MSI для групповой политики?

ExeTup собирает Setup.exe. Он устанавливается в тихом режиме с ключом /S, чего достаточно для большинства сценариев скриптового развёртывания. Для политик, принимающих только MSI, подходящий инструмент — WiX.

С какими версиями .NET это работает?

С любыми, которые создают папку публикации: .NET 6, 7, 8, 9 и новее, а также приложения .NET Framework, собранные в Visual Studio (используйте выход bin\Release).

Похожие руководства