Автоматическое повышение привилегий процесса?

Я пытаюсь установить службу с помощью 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";, но, похоже, это не решило проблему.

Ответ 1

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

startInfo.Verb = "runas";

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

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

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

Ответ 2

Этот код ставит все вышеперечисленное и перезапускает текущее приложение wpf с помощью admin privs:

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, добавьте новый файл манифеста приложения, измените файл, чтобы у вас был требуемый администратор, как показано выше.

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

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

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

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

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