Avatar ·

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

Всем привет! Пишу небольшое приложение на C# (Windows Forms), которое должно редактировать системные файлы и ключи реестра. Проблема в том, что при обычном запуске программа работает нормально, но как только дело доходит до записи в Program Files или изменения системных настроек, вылетает исключение System.UnauthorizedAccessException. Я понимаю, что нужно запускать приложение с повышенными привилегиями, но как это сделать программно? Пробовал добавить манифест, но Visual Studio ругается. Видел на форумах, что можно использовать права администратора через app.manifest, но у меня нет этого файла в проекте. Вот пример кода, который пытается записать лог в защищенную папку: ```csharp using System; using System.IO; class Program { static void Main() { string path = @"C:\Program Files\MyApp\config.ini"; File.WriteAllText(path, "Настройки сохранены"); Console.WriteLine("Успех!"); } } ``` Код падает с ошибкой доступа. Как сделать так, чтобы при запуске программы сразу появлялось окно UAC с запросом на повышение прав? Нужно решение для .NET Framework 4.7.2 и Windows 10/11. Заранее спасибо! <<>>

Решение: добавление манифеста с запросом прав администратора

Проблема в том, что ваше приложение по умолчанию запускается с правами текущего пользователя. Чтобы заставить Windows запрашивать повышение привилегий через UAC, нужно добавить в проект манифест с указанием уровня выполнения requireAdministrator.

Шаг 1. Создайте файл манифеста

В Visual Studio: Project → Add New Item → Application Manifest File (обычно называется app.manifest). Если такого пункта нет, создайте вручную файл app.manifest в корне проекта.

Шаг 2. Отредактируйте манифест

Найдите в файле секцию requestedExecutionLevel и измените её:

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

Полный пример манифеста:

<?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>

Шаг 3. Подключите манифест в проекте

В Project Properties → Application → Resources → Manifest выберите созданный файл. Если используете .NET Core / .NET 5+, добавьте в .csproj:

<PropertyGroup>
  <ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>

Шаг 4. Проверьте работу

После пересборки при запуске появится окно UAC. Если пользователь нажмёт "Да", код выполнится с правами администратора. Если "Нет" — приложение завершится с ошибкой.

Альтернативный способ: проверка прав в коде

Если нужно проверить, запущено ли приложение с правами администратора, используйте:

using System.Security.Principal;

public static bool IsAdministrator()
{
    var identity = WindowsIdentity.GetCurrent();
    var principal = new WindowsPrincipal(identity);
    return principal.IsInRole(WindowsBuiltInRole.Administrator);
}

Важные моменты:

  • UAC обязателен: даже если пользователь — администратор, без манифеста приложение получит токен с пониженными правами.
  • Отладка: Visual Studio нужно запускать от имени администратора, иначе манифест не сработает при отладке.
  • Для .NET Core: механизм тот же, но манифест можно встроить через ресурсы.

Исправленный код с манифестом:

using System;
using System.IO;
using System.Security.Principal;

class Program
{
    static void Main()
    {
        if (!IsAdministrator())
        {
            Console.WriteLine("Требуются права администратора!");
            return;
        }

        string path = @"C:\Program Files\MyApp\config.ini";
        Directory.CreateDirectory(Path.GetDirectoryName(path));
        File.WriteAllText(path, "Настройки сохранены");
        Console.WriteLine("Успех!");
    }

    static bool IsAdministrator()
    {
        var identity = WindowsIdentity.GetCurrent();
        var principal = new WindowsPrincipal(identity);
        return principal.IsInRole(WindowsBuiltInRole.Administrator);
    }
}
<<>>

Программный запрос повышения прав через Process.Start

Если вы не хотите добавлять манифест (например, приложение должно работать и без прав администратора для базовых функций), можно запустить копию процесса с повышенными привилегиями:

using System;
using System.Diagnostics;

public static void RestartAsAdmin()
{
    var processInfo = new ProcessStartInfo
    {
        FileName = Process.GetCurrentProcess().MainModule.FileName,
        UseShellExecute = true,
        Verb = "runas" // ключевой параметр
    };

    try
    {
        Process.Start(processInfo);
        Environment.Exit(0); // закрыть текущий процесс
    }
    catch (Exception ex)
    {
        Console.WriteLine("Не удалось повысить права: " + ex.Message);
    }
}

Как использовать:

  • Вызовите RestartAsAdmin() при старте, если текущие права недостаточны.
  • Пользователь увидит окно UAC. Если он согласится — запустится новая копия с правами администратора.
  • Старый процесс завершается, чтобы не было дублирования.

Недостатки метода:

  • Приложение перезапускается — теряются аргументы командной строки (их нужно передавать вручную).
  • Не подходит для служб Windows.
  • Может сбить с толку пользователя неожиданным перезапуском.

Этот подход удобен, когда основная часть программы работает без прав, а административные функции вызываются редко (например, установка обновлений).