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

StackOverflow https://stackoverflow.com/questions/573086

Вопрос

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

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

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

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

Это было полезно?

Решение

Я не верю, что возможно улучшить текущий процесс.Насколько я понимаю, в 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 .

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

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

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

Смотрите этот вопрос.

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

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

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.Закройте приложение.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top