Необходимость UAC для консольного приложения
У меня есть консольное приложение, для которого требуется использовать код, требующий уровня администратора. Я прочитал, что мне нужно добавить файл манифеста 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). Как я могу решить эту проблему?
Update
Я могу заставить его работать, если я запустил решение в Administrator или когда я запустил /bin/ *.exe в Administrator. Я все еще задаюсь вопросом, возможно ли иметь что-то, что будет появляться, когда приложение запускается, а не прямое нажатие правой кнопки мыши > Запуск от имени администратора?
Ответы
Ответ 1
Вам нужно встроить манифест UAC в качестве встроенного ресурса Win32. См. Добавление манифеста UAC в управляемый код.
Короче говоря, вы используете инструмент командной строки Windows SDK для вставки его в свой исполняемый файл.
Вы можете автоматизировать это как шаг после сборки, поставив следующую строку в качестве задачи пост-сборки в свойствах проекта VS:
mt.exe -manifest "$(ProjectDir)$(TargetName).exe.manifest" -updateresource:"$(TargetDir)$(TargetName).exe;#1"
Ответ 2
Для всех, кто использует Visual Studio, это очень просто. Я собирался настроить SDK для Windows и выполнить шаги post-build mt.exe и все это, прежде чем реализовать его в VS. Я решил, что записал его для потомков.
- Проект | Добавить новый элемент → Элементы Visual С# → Файл манифеста приложений
- Откройте app.manifest, измените requestExecutionLevel. @level на "requireAdministrator"
- Построить
Та-да
Ответ 3
Ответ Скотта будет делать то, что вы просили, но Microsoft рекомендует, чтобы консольные приложения отображали сообщение "отказ в доступе", а не запрос на повышение.
Из http://msdn.microsoft.com/en-us/library/bb756922.aspx:
Консольное приложение представляет свой вывод в окне консоли, а не с отдельным пользовательским интерфейсом. Если для приложения требуется полный администратор токен доступа для запуска, то это приложение необходимо запустить из приподнятое консольное окно.
Для консольных приложений вы должны сделать следующее:
-
Отметьте, что ваше приложение "asInvoker": вы можете сделать это, создав манифест вашего приложения, в котором вы установите RequestedExecutionLevel == asInvoker. Эта настройка позволяет вызывающим абонентам из невыполненных контекстов создавать ваш процесс, что позволяет им перейти к шагу 2.
-
Предоставьте сообщение об ошибке, если приложение запущено без токена доступа для полного доступа администратора. Если приложение запущено на не-поднятой консоли, ваше приложение должно предоставить краткое сообщение и выйти. Рекомендуемое сообщение: "Доступ запрещен. Для использования выбранных параметров необходимы разрешения администратора. Для выполнения этих задач используйте командную строку администратора."
Приложение также должно вернуть код ошибки ERROR_ELEVATION_REQUIRED при неудаче запуска для облегчения написания сценариев.
Мой код С# для этого ниже. Он протестирован в Windows XP (администратор → ok, стандартный пользователь → запрещен) и Windows Server 2008 (повышенный администратор → ok, неа повышенный администратор → отклонен, стандартный пользователь → отклонен).
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);
}