Повышение привилегий процесса программно?


147

Я пытаюсь установить службу с помощью InstallUtil.exe, но вызывается через Process.Start. Вот код:

ProcessStartInfo startInfo = new ProcessStartInfo (m_strInstallUtil, strExePath);
System.Diagnostics.Process.Start (startInfo);

где m_strInstallUtil- полный путь и исполняемый файл «InstallUtil.exe», а strExePathтакже полный путь / имя моей службы.

Запуск синтаксиса командной строки из командной строки с повышенными правами работает; Запуск из моего приложения (с использованием вышеуказанного кода) не. Я предполагаю, что имею дело с какой-то проблемой повышения прав, так как мне запустить мой процесс с повышенными правами? Нужно ли смотреть на ShellExecuteэто?

Это все в Windows Vista. Я запускаю процесс в отладчике VS2008 с повышенными правами администратора.

Я также попытался установить, startInfo.Verb = "runas";но это, похоже, не решило проблему.


После того, как я добавил startInfo.UseShellExecute = true;в дополнение к startInfo.Verb = "runas";этому работал нормально для меня.
— Мэтт

Ответы:


172

Вы можете указать, что новый процесс должен быть запущен с повышенными разрешениями, установив для свойства Verb вашего объекта startInfo значение runas, как показано ниже:

startInfo.Verb = "runas";

Это приведет к тому, что Windows будет вести себя так, как если бы процесс был запущен из Проводника с помощью команды меню «Запуск от имени администратора».

Это означает, что появится запрос UAC, и пользователь должен будет его подтвердить: если это нежелательно (например, потому что это может произойти в середине длительного процесса), вам необходимо запустить весь хост-процесс с повышенные разрешения для создания и встраивания манифеста приложения (UAC), требующие «наивысшего доступного» уровня выполнения: это приведет к тому, что приглашение UAC появится, как только ваше приложение будет запущено, и заставит все дочерние процессы запускаться с повышенными разрешениями без дополнительных запросов ,

Редактировать: Я вижу, вы только что отредактировали свой вопрос, чтобы заявить, что "runas" не работает для вас. Это действительно странно, как и должно быть (и делает для меня в нескольких производственных приложениях). Требование выполнения родительского процесса с повышенными правами путем встраивания манифеста, безусловно, должно работать.


9
«Руны» у меня тоже не сработали. Может быть, он работает только с выключенным UAC?
— Дирк Воллмар

18
@ LukePuplett Я бы поблагодарил их. Это отличный способ уменьшить установку руткитов без фактического разделения ролей пользователей.
— Колтон

6
@ Sparksis, но есть и другая точка зрения. Люди, которые знают, как защитить свою ОС, знают, как это сделать без UAC. И фиктивные пользователи, которые не знают, что такое защита, они нажимают «ДА» каждый раз, когда видят окно UAC. Кроме того, ничто не может помешать злоумышленникам-вирусописателям использовать эксплойты, чтобы обойти это;) Поэтому я согласен с LukePuplett =)
— Jet

24
Похоже, что вы также должны установить, startInfo.ShellExecute=trueчтобы это работало ... также я не смог заставить этот метод работать с исполняемыми файлами, находящимися в общем сетевом ресурсе (нужно скопировать их в локальный временный каталог перед запуском). ..
— TCC

7
@Jet Извините, но это неправильное мышление. Каждый раз, когда диалоговое окно UAC отображается во время установки, это сбой системы. Там, где это ценно, вы видите блок UAC без запуска чего-либо, требующего повышения прав. Не имеет значения, насколько профессионально вы - любой из нас - думаете, что мы находимся на наших компьютерах, вы не можете волшебным образом заблокировать загрузку с нулевыми днями / без дисков (например, недавнюю на официальном сайте Нобелевской премии). Если бы вы зашли на этот сайт и получили приглашение UAC, вы бы знали, что что-то не так. С отключенным UAC вы никогда не узнаете, что присоединились к ботнету. Стоимость предварительного предупреждения заключается в том, что иногда приходится нажимать кнопку Да
— Basic

46

Этот код объединяет все вышеперечисленное и перезапускает текущее приложение wpf с правами администратора:

if (IsAdministrator() == false)
{
    // Restart program and run as admin
    var exeName = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
    ProcessStartInfo startInfo = new ProcessStartInfo(exeName);
    startInfo.Verb = "runas";
    System.Diagnostics.Process.Start(startInfo);
    Application.Current.Shutdown();
    return;
}

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


// To run as admin, alter exe manifest file after building.
// Or create shortcut with "as admin" checked.
// Or ShellExecute(C# Process.Start) can elevate - use verb "runas".
// Or an elevate vbs script can launch programs as admin.
// (does not work: "runas /user:admin" from cmd-line prompts for admin pass)

Обновление: способ манифеста приложения является предпочтительным:

Щелкните правой кнопкой мыши проект в Visual Studio, добавьте, новый файл манифеста приложения, измените файл так, чтобы вы установили requireAdministrator, как показано выше.

Проблема с оригинальным способом: если вы поместите код перезапуска в app.xaml.cs OnStartup, он все равно может ненадолго запустить главное окно, даже если было вызвано завершение работы. Мое главное окно лопнуло, если бы app.xaml.cs init не был запущен и в определенных условиях гонки это сделало бы это.


Смотрите ниже для улучшения.
— JCCyC

requireAdministrator не работает в моем случае. Поэтому я должен был сделать это по-своему. Это решило мою проблему! Спасибо. Но мне пришлось установить для Single Instance Application значение false.
— Крис

Это сработало для меня. Я также передал оригинал string[] argsв новый процесс.
— DotNetPadawan

21

В соответствии со статьей Крис Корио: научите свои приложения хорошо играть с управлением учетными записями пользователей Windows Vista, журнал MSDN, январь 2007 г. , только ShellExecuteпроверяет встроенный манифест и запрашивает повышение прав у пользователей, если это необходимо, CreateProcessа другие API этого не делают. Надеюсь, поможет.

Смотрите также: та же статья, что и .chm .


7
[PrincipalPermission(SecurityAction.Demand, Role = @"BUILTIN\Administrators")]

Это будет сделано без UAC - не нужно начинать новый процесс. Если работающий пользователь является членом группы администраторов, как в моем случае.


3
Используя этот код, я получаю ошибку разрешения: «Запрос на разрешение объекта безопасности не выполнен». :(
— Леонардо

Возможно, «если бегущий пользователь является членом Admin» *
— hB0

1
интересно - это может быть любой метод, не только метод действия (я даже попробовал его на методе, определенном на странице ASPX)
— Simon_Weaver

1

Вы должны использовать Олицетворение, чтобы поднять государство.

WindowsIdentity identity = new WindowsIdentity(accessToken);
WindowsImpersonationContext context = identity.Impersonate();

Не забудьте отменить олицетворенный контекст, когда закончите.


28
Вы не сказали, как получить accessToken. LogonUser предоставит пользователю ограниченный контекст безопасности, когда UAC включен.
— CWA

Если вы используете VSTS, вы можете получить Личный токен доступа из настроек на веб-портале. (Ищите значок настроек рядом с картинкой пользователя.) MSDocs
— Су Ллевеллин
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.