UAC нужен для консольного приложения - PullRequest
26 голосов
/ 22 октября 2008

У меня есть консольное приложение, которое требует использования некоторого кода, который требует уровня администратора. Я прочитал, что мне нужно добавить файл манифеста myprogram.exe.manifest, который выглядит так:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="requireAdministrator">
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>

Но он все равно не поднимает UAC (в консоли или при отладке в VS). Как я могу решить эту проблему?

Обновление

Я могу заставить его работать, если я запускаю решение в Администраторе или когда я запускаю /bin/*.exe в Администраторе. Я все еще задаюсь вопросом, возможно ли иметь что-то, что появится при запуске приложения вместо явного щелчка правой кнопкой мыши> Запуск от имени администратора?

Ответы [ 3 ]

53 голосов
/ 03 февраля 2010

Для тех, кто использует Visual Studio, это очень просто. Я собирался настроить Windows SDK и выполнить шаги после сборки mt.exe и все это, прежде чем понять, что он встроен в VS. Я решил записать это для потомков.

  1. Проект | Добавить новый элемент -> Элементы Visual C # -> Файл манифеста приложения
  2. Откройте app.manifest, измените уровень требуемого_исполнения. @ Level на «requireAdministrator»
  3. Сложение

Та-да

24 голосов
/ 21 апреля 2010

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

С http://msdn.microsoft.com/en-us/library/bb756922.aspx:

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

Для консольных приложений необходимо сделать следующее:

  1. Отметьте, что ваше приложение «asInvoker»: вы можете сделать это, написав манифест своего приложения, в котором вы задали RequestedExecutionLevel == asInvoker. Эта настройка позволяет вызывающим абонентам из невысокого контекста создавать процесс, что позволяет им перейти к шагу 2.

  2. Предоставить сообщение об ошибке, если приложение запущено без маркера полного доступа администратора: если приложение запущено в консоли без прав доступа, ваше приложение должно дать краткое сообщение и выйти. Рекомендуемое сообщение: «Отказано в доступе. Для использования выбранных параметров необходимы разрешения администратора. Для выполнения этих задач используйте командную строку администратора».

При сбое запуска приложение также должно вернуть код ошибки ERROR_ELEVATION_REQUIRED, чтобы упростить создание сценариев.

Мой код C # для этого ниже. Он протестирован в Windows XP (администратор -> хорошо, обычный пользователь -> запрещен) и Windows Server 2008 (администратор с повышенными правами -> нормально, администратор без повышенных прав -> запрещен, обычный пользователь -> запрещен).

static int Main(string[] args)
{
    if (!HasAdministratorPrivileges())
    {
        Console.Error.WriteLine("Access Denied. Administrator permissions are " +
            "needed to use the selected options. Use an administrator command " +
            "prompt to complete these tasks.");
        return 740; // ERROR_ELEVATION_REQUIRED
    }

    ...
    return 0;
}

private static bool HasAdministratorPrivileges()
{
    WindowsIdentity id = WindowsIdentity.GetCurrent();
    WindowsPrincipal principal = new WindowsPrincipal(id);
    return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
8 голосов
/ 03 ноября 2008

Вам необходимо встроить манифест UAC как встроенный ресурс Win32. См. Добавление манифеста UAC к управляемому коду .

Короче говоря, вы используете инструмент командной строки Windows SDK для встраивания его в исполняемый файл.

Вы можете автоматизировать это как шаг после сборки, поместив следующую строку в качестве задачи после сборки в свойствах проекта VS:

mt.exe -manifest "$(ProjectDir)$(TargetName).exe.manifest" -updateresource:"$(TargetDir)$(TargetName).exe;#1"
...