Как повысить привилегии только в случае необходимости?

Этот вопрос относится к Windows Vista!

У меня есть приложение, которое обычно работает без административных привилегий. Существует один вид деятельности, который нуждается в административных привилегиях, но я не хочу запускать приложение с более высокими привилегиями, когда я знаю, что большая часть времени пользователь даже не использует эту функцию.

Я думаю об определенном методе, с помощью которого я могу поднять привилегии приложения на какое-либо событие (например, нажатие кнопки). Пример:

Если пользователь нажмет эту кнопку, ему будет предложено диалоговое окно UAC или согласие. Как я могу это сделать?

Я не считаю, что можно поднять текущий процесс. Как я понимаю, он встроен в Windows Vista, когда права администратора предоставляются процессу при запуске. Если вы посмотрите на различные программы, которые используют UAC, вы должны увидеть, что они фактически запускают отдельный процесс каждый раз, когда необходимо выполнить административное действие (диспетчер задач – один, Paint.NET – это другой, последний из которых является .NET-приложением на самом деле ).

Типичным решением этой проблемы является указание аргументов командной строки при запуске повышенного процесса (предложение abatishchev – это один из способов сделать это), так что запущенный процесс знает только, чтобы отобразить определенное диалоговое окно, а затем выйти после того, как это действие было выполнено завершено. Таким образом, для пользователя не должно быть заметно, чтобы новый процесс был запущен, а затем вышел из него и скорее появлялся, как если бы было открыто новое диалоговое окно в одном и том же приложении (особенно, если вы обнаружили хакерство, чтобы сделать главное окно повышенный процесс – дочерний процесс родительского процесса). Если вам не нужен интерфейс для повышенного доступа, еще лучше.

Для полного обсуждения UAC на Vista я рекомендую вам ознакомиться с этой статьей на эту тему (примеры кода на C ++, но я подозреваю, что вам нужно будет использовать WinAPI и P / Invoke для выполнения большинства вещей в C # так или иначе). Надеюсь, вы, по крайней мере, видите правильный подход, хотя разработка UAC-совместимой программы далека от тривиальной …

Как было сказано там :

Process.StartInfo.UseShellExecute = true; Process.StartInfo.Verb = "runas"; 

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

В следующей статье MSDN KB 981778 описано, как «самоподнять» приложение:

http://support.microsoft.com/kb/981778

Он содержит загружаемые образцы в Visual C ++, Visual C #, Visual Basic.NET.

Этот подход связан с необходимостью запуска отдельного процесса, но на самом деле это первоначальное приложение, которое перезапускается, работает как повышенный пользователь. Тем не менее это может быть очень полезно в некоторых контекстах, где нецелесообразно дублировать код в отдельном исполняемом файле.

Чтобы удалить высоту, вам нужно выйти из приложения.

Вам нужен прозвище UAC и код для запуска повышенного уровня как COM-объект.

См. Этот вопрос.

Документация по MSDN.

Я знаю, что это старый пост, но это ответит на любого другого, кто встречает предложение MarcP. Сообщение msdn, на которое он ссылается, действительно перезапускает приложения во всех примерах кода. Образцы кода используют глагол runas предложенный уже в других предложениях.

Я загрузил код, чтобы убедиться, но это из оригинальной статьи msdn:

4. Нажмите Да, чтобы подтвердить высоту. Затем исходное приложение перезапускается, работая как администратор с повышенными правами.
5. Закройте приложение.

Возможно, кому-то пригодится этот простой пример:

 using System; using System.Linq; using System.Reflection; using System.Diagnostics; using System.Security.Principal; using System.Windows.Forms; namespace WindowsFormsApp1 { internal static class Program { private class Form1 : Form { internal Form1() { var button = new Button{ Dock = DockStyle.Fill }; button.Click += (sender, args) => RunAsAdmin(); Controls.Add(button); ElevatedAction(); } } [STAThread] internal static void Main(string[] arguments) { if (arguments?.Contains("/run_elevated_action") == true) { ElevatedAction(); return; } Application.Run(new Form1()); } private static void RunAsAdmin() { var path = Assembly.GetExecutingAssembly().Location; using (var process = Process.Start(new ProcessStartInfo(path, "/run_elevated_action") { Verb = "runas" })) { process?.WaitForExit(); } } private static void ElevatedAction() { MessageBox.Show([email protected]"IsElevated: {IsElevated()}"); } private static bool IsElevated() { using (var identity = WindowsIdentity.GetCurrent()) { var principal = new WindowsPrincipal(identity); return principal.IsInRole(WindowsBuiltInRole.Administrator); } } } } 
Давайте будем гением компьютера.