Как заставить .NET приложение всегда запускаться от администратора? Полный гайд

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Как заставить .NET приложение всегда запускаться от имени администратора? (И не сойти с ума)

Привет, коллега! Если ты когда-нибудь писал утилиту для работы с реестром, установки служб Windows или просто пытался сохранить файл в C:\Program Files, ты наверняка сталкивался с этим: приложение падает с ошибкой "Access Denied", пользователь пожимает плечами, а ты чешешь затылок. Знакомая ситуация? Добро пожаловать в мир UAC (User Account Control) и вечной борьбы за права администратора.

Сегодня мы разберем самый популярный вопрос на Stack Overflow (да-да, тот самый, с тысячами просмотров): "How do I force my .NET application to run as administrator?". Мы не просто скопируем ответ, мы поймем, как это работает, и напишем красивый код на C#. Поехали!

Почему просто так нельзя? Магия UAC

Windows, начиная с Vista, не доверяет приложениям по умолчанию. Даже если ты залогинился как "Администратор", твой процесс получает маркер с фильтрованными правами. Это сделано для безопасности: чтобы вирус не мог просто так переписать системные файлы.

Когда ты запускаешь .exe, система смотрит на его манифест. Если там нет специальной пометки, приложение работает с правами обычного пользователя. Наша задача — добавить эту пометку.

Способ 1: Добавляем манифест (правильный путь для .NET Framework)

Это стандартный и самый простой способ для классических Windows Forms или WPF приложений на .NET Framework.

Шаг 1: Создаем или редактируем файл app.manifest

В Visual Studio кликни правой кнопкой по проекту → Add → New Item → Application Manifest File. Если файл уже есть (например, app.manifest), просто открой его.

Ты увидишь XML с кучей комментариев. Нас интересует секция requestedExecutionLevel. Приведи её к такому виду:

<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges>
        <!-- ВАЖНО: Вот эта строчка -->
        <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>

Обрати внимание на level="requireAdministrator". Есть ещё два значения:

  • asInvoker — запуск с правами родительского процесса (по умолчанию).
  • highestAvailable — запуск с максимально доступными правами для текущего пользователя.

Шаг 2: Связываем манифест с проектом (если не сработало автоматически)

Открой свойства проекта (правой кнопкой по проекту → Properties). На вкладке Application найди раздел Resources и в выпадающем списке "Manifest" выбери "app.manifest".

Готово! Теперь при запуске твоего .exe Windows сразу покажет окно UAC: "Разрешить этому приложению вносить изменения на вашем устройстве?". Если пользователь нажмет "Да" — приложение получит полные права администратора.

Способ 2: Программный рестарт с повышением (для .NET Core / .NET 5+)

Этот способ универсален и работает даже в .NET Core, .NET 5/6/7/8 и .NET Framework. Иногда манифест не подходит, потому что:

  • Ты хочешь, чтобы приложение запускалось без прав, но некоторые функции требовали повышения.
  • Ты используешь консольное приложение или службу.

Идея проста: приложение проверяет, есть ли у него права. Если нет — оно запускает само себя заново, но с ключом runas (от имени администратора).

Код проверки и повышения

using System;
using System.Diagnostics;
using System.Security.Principal;
using System.Windows.Forms;

public static class AdminHelper
{
    public static bool IsRunningAsAdministrator()
    {
        // Получаем текущего пользователя Windows
        WindowsIdentity identity = WindowsIdentity.GetCurrent();
        WindowsPrincipal principal = new WindowsPrincipal(identity);
        // Проверяем, входит ли он в группу администраторов
        return principal.IsInRole(WindowsBuiltInRole.Administrator);
    }

    public static void RestartAsAdministrator()
    {
        if (!IsRunningAsAdministrator())
        {
            // Получаем путь к текущему исполняемому файлу
            var exePath = Application.ExecutablePath; // Для WinForms
            // Для консольного приложения: Process.GetCurrentProcess().MainModule.FileName

            var startInfo = new ProcessStartInfo(exePath)
            {
                // Verb = "runas" заставляет Windows показать UAC
                Verb = "runas",
                UseShellExecute = true
            };

            try
            {
                Process.Start(startInfo);
                // Закрываем текущее приложение с низкими правами
                Application.Exit();
            }
            catch (Exception ex)
            {
                // Пользователь отменил UAC или произошла ошибка
                MessageBox.Show("Не удалось получить права администратора: " + ex.Message);
            }
        }
    }
}

Как использовать в Program.cs

static void Main()
{
    // Проверяем права при старте
    if (!AdminHelper.IsRunningAsAdministrator())
    {
        AdminHelper.RestartAsAdministrator();
        return; // Выходим, чтобы не запускать приложение дважды
    }

    // Если мы здесь — у нас есть права администратора
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new MainForm());
}

Важно: При использовании Verb = "runas" приложение запускается как новый процесс. Текущий процесс нужно закрыть, иначе ты получишь два экземпляра программы.

Способ 3: Комбинированный (для гибких архитектур)

Самый элегантный вариант — использовать манифест для основного функционала, но добавить программную проверку для подстраховки. Например, если приложение запущено без UAC (как служба или в среде без графического интерфейса).

if (!AdminHelper.IsRunningAsAdministrator())
{
    // Пробуем рестарт с UAC
    AdminHelper.RestartAsAdministrator();
}
else
{
    // Запускаем основную логику
    Application.Run(new MainForm());
}

Частые ошибки и "грабли"

Ошибка 1: "Я добавил манифест, но UAC не появляется!"

Причины: