Как повысить привилегии только при необходимости?
этот вопрос относится к Windows Vista!
У меня есть приложение, которое нормально работает без административных привилегий. Существует одно действие, которое требует административных привилегий, но я не хочу запускать само приложение с более высокими привилегиями, когда я знаю, что большую часть времени пользователь даже не будет использовать эту функцию.
Я думаю об определенном методе, с помощью которого я могу повысить привилегии приложения на некоторое событие (например, нажатие кнопки). Пример:
если пользователь нажимает эту кнопку, то ему предлагается диалоговое окно UAC или согласие. Как я могу это сделать?
6 ответов:
Я не верю, что можно поднять запущенных процессов. Он встроен в Windows Vista, что права администратора предоставляются процессу при запуске, как я понимаю. Если вы посмотрите на различные программы, которые используют UAC, вы должны увидеть, что они фактически запускают отдельный процесс каждый раз, когда необходимо выполнить административное действие (Диспетчер задач-один, Paint.NET другой, последний является приложением .NET на самом деле).
типовое решение к этой проблеме относится указание аргументов командной строки при запуске повышенного процесса (предложение абатищева-один из способов сделать это), чтобы запущенный процесс знал только отображение определенного диалогового окна, а затем выход после завершения этого действия. Таким образом, для пользователя вряд ли должно быть заметно, что новый процесс был запущен, а затем вышел, и скорее будет выглядеть так, как будто новое диалоговое окно в том же приложении было открыто (особенно если вы какой-то хакер, чтобы сделать основной окно повышенного процесса дочерний родительский процесс). Если вам не нужен пользовательский интерфейс для повышенного доступа, еще лучше.
для полного обсуждения UAC на Vista, я рекомендую вам посмотреть это очень Через статьи по этому вопросу (примеры кода находятся в C++, но я подозреваю, что вам нужно будет использовать WinAPI и P/Invoke, чтобы сделать большинство вещей в C# в любом случае). Надеюсь, теперь вы, по крайней мере, видите правильный подход, хотя разработка совместимой с UAC программы далека тривиальный...
Как сообщил здесь:
Process.StartInfo.UseShellExecute = true; Process.StartInfo.Verb = "runas";
запустит процесс как администратор, чтобы сделать все, что вам нужно с реестром, но вернуться к вашему приложению с обычными привилегиями.
в следующей статье 981778 MSDN KB описывается ,как "самостоятельно поднять" приложение:
http://support.microsoft.com/kb/981778
содержит примеры в Visual C++ или Visual C# в Visual Basic.NET.
этот подход позволяет обойти необходимость запуска отдельного процесса, но на самом деле это исходное приложение, которое перезапускается, работает как пользователь с повышенными правами. Тем не менее, это все еще может быть очень полезным в некоторых контекстах, где дублировать код в отдельном исполняемом файле нецелесообразно.
чтобы удалить высоту, вам нужно выйти из приложения.
Я знаю, что это старый пост, но это в ответ на все, кто сталкивается с предложением 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($@"IsElevated: {IsElevated()}"); } private static bool IsElevated() { using (var identity = WindowsIdentity.GetCurrent()) { var principal = new WindowsPrincipal(identity); return principal.IsInRole(WindowsBuiltInRole.Administrator); } } } }