Повышение привилегий процесса программно? - PullRequest
136 голосов
/ 25 сентября 2008

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

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

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

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

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

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

Ответы [ 5 ]

166 голосов
/ 25 сентября 2008

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

startInfo.Verb = "runas";

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

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

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

39 голосов
/ 06 июня 2012

Этот код объединяет все вышеперечисленное и перезапускает текущее 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 не был запущен, и в определенных условиях гонки он это сделал.

21 голосов
/ 24 октября 2008

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

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

7 голосов
/ 12 января 2012
[PrincipalPermission(SecurityAction.Demand, Role = @"BUILTIN\Administrators")]

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

0 голосов
/ 25 сентября 2008

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

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

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

...