Підвищення привілеїв процесу програмно?


147

Я намагаюся встановити службу за допомогою 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";але це, здається, не вирішило проблему.


Після того, як я додав, що startInfo.UseShellExecute = true;на додаток до startInfo.Verb = "runas";цього, він добре працював для мене.
Мет

Відповіді:


172

Ви можете вказати, що новий процес слід починати з підвищених дозволів, встановивши для властивості Verb об’єкта startInfo значення "runas", як описано нижче:

startInfo.Verb = "runas";

Це призведе до того, що Windows поводитиметься так, ніби процес був запущений із Провідника за допомогою команди меню «Запустити як адміністратор».

Це означає, що з'явиться підказка UAC і її потрібно підтвердити користувачеві: якщо це небажано (наприклад, це сталося в середині тривалого процесу), вам потрібно буде запустити весь хост-процес з підвищені дозволи для створення та вбудовування маніфесту програми (UAC), щоб вимагати рівня виконання "найвищий доступний": це призведе до того, що запит UAC з'явиться, як тільки ви запустите додаток, і призведе до запуску всіх дочірніх процесів із підвищеними дозволами без додаткових підказок. .

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


9
"runas" також не працював для мене. Може бути, він працює лише з вимкненим UAC?
Дірк Волмар

18
@LukePuplett Я б вдячний їм. Це прекрасний спосіб пом'якшити встановлення root-kit, не фактично повністю розділивши ролі користувача.
Колтон

6
@Sparksis, але є й інша точка зору. Люди, які вміють захищати свою ОС, знають, як це зробити без UAC. І фіктивні користувачі, які не знають, що таке захист, вони щоразу, коли бачать вікно UAC, клацають "ТАК". Також ніщо не може перешкодити злочинцям-авторам-вірусам використовувати подвиги, щоб обійти його;) Тож я згоден з LukePuplett =)
Jet

24
Схоже, ви повинні налаштувати startInfo.ShellExecute=trueтак, щоб це працювало ... також мені не вдалося змусити цей метод працювати з виконуваними файлами, які знаходяться в мережевій спільній доступності (перед запуском доводиться копіювати їх у локальну тимчасову директорію). ..
TCC

7
@Jet Вибачте, але це неправильне мислення. Кожен раз, коли під час встановлення відображається діалогове вікно UAC, це є збоєм у роботі системи. Де це цінно, коли ви бачите поле UAC, не запускаючи щось, що вимагає піднесення. Не важливо, наскільки ви, будь-хто з нас, думаєте, що ми працюємо на своїх ПК, ви не можете магічно заблокувати завантаження нульових днів / драйверів (наприклад, останні на офіційному сайті Нобелівської премії). Якщо ви перейшли на цей сайт і отримали підказку UAC, ви б знали, що щось не так. З вимкненим UAC ви ніколи не дізнаєтесь, що тільки що приєдналися до ботнету. Вартість попереднього попередження полягає в тому, що потрібно періодично клацати Так
Основні

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)

Оновлення: спосіб маніфесту додатка бажаний:

Клацніть правою кнопкою миші проект у візуальній студії, додайте, новий файл маніфесту програми, змініть файл, щоб у вас був набірAdAd Administrator, як показано вище.

Проблема з оригінальним способом: Якщо ви помістите код перезавантаження в app.xaml.cs OnStartup, воно все ще може ненадовго запустити головне вікно, навіть незважаючи на закриття. Моє головне вікно вибухнуло, якщо app.xaml.cs init не був запущений і в певних умовах гонки це зробить.


Детальнішу інформацію див. Нижче.
JCCyC

requAdministrator не працював у моєму випадку. Тому я повинен був зробити це по-своєму. Це вирішило мою проблему! спасибі. Але мені довелося встановити програму Single Instance на значення false.
chris

Це працювало для мене. Я також передав оригінал string[] argsдо процесу відновлення.
DotNetPadawan

21

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

Дивіться також: та сама стаття, як .chm .


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

Це обійдеться без UAC - не потрібно починати новий процес. Якщо поточний користувач є членом групи адміністраторів, як у моєму випадку.


3
Використовуючи цей код, я отримую помилку дозволу: "Запит дозволу суб'єкта безпеки не вдався." :(
Леонардо

Можливо, "Якщо поточний користувач є членом адміністратора" *
hB0

1
що цікаво - це може бути застосовано будь-який метод, а не лише метод дій (я навіть спробував це на методі, визначеному на сторінці ASPX)
Simon_Weaver

1

Ви повинні використовувати себе, щоб підняти державу.

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

Не забудьте скасувати підроблений контекст, коли закінчите.


28
Ви не сказали, як отримати accessToken. LogonUser надасть користувачеві обмежений контекст безпеки при включенні UAC.
cwa

Якщо ви використовуєте VSTS, ви можете отримати маркер особистого доступу з налаштувань веб-порталу. (Шукайте значок налаштування поруч із зображенням користувача.) MSDocs
Su Llewellyn
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.