Как повысить привилегии только при необходимости?
Этот вопрос относится к 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";
запустит процесс от имени администратора, чтобы сделать с реестром все, что вам нужно, но вернется к вашему приложению с обычными привилегиями.
В следующей статье MSN KB 981778 описывается, как "поднять" приложение:
http://support.microsoft.com/kb/981778
Он содержит загружаемые примеры в Visual C++, Visual C#, Visual Basic.NET.
Этот подход избавляет от необходимости запускать отдельный процесс, но на самом деле это исходное приложение, которое перезапускается и работает как пользователь с повышенными правами. Тем не менее, это все еще может быть очень полезным в некоторых контекстах, где нецелесообразно дублировать код в отдельный исполняемый файл.
Чтобы удалить высоту, вам нужно выйти из приложения.
Вам нужен псевдоним UAC и код для запуска с повышенными правами как COM-объект.
Возможно, кому-то пригодится этот простой пример:
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);
}
}
}
}
Я знаю, что это старый пост, но это ответ любого, кто сталкивается с предложением MarcP. Сообщение msdn, на которое он ссылался, действительно перезапускает приложения во всех примерах кода. Примеры кода используют runas
глагол предлагается уже в других предложениях.
Я скачал код, чтобы убедиться, но это из оригинальной статьи msdn:
4. Нажмите Да, чтобы подтвердить высоту. Затем исходное приложение перезапускается с правами администратора.
5. Закройте приложение.