Как повысить привилегии только при необходимости? - PullRequest
82 голосов
/ 21 февраля 2009

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

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

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

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

Ответы [ 6 ]

56 голосов
/ 21 февраля 2009

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

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

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

15 голосов
/ 21 февраля 2009

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

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

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

13 голосов
/ 24 октября 2012

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

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

Содержит загружаемые примеры в Visual C ++, Visual C #, Visual Basic.NET.

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

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

4 голосов
/ 21 февраля 2009

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

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

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

2 голосов
/ 05 марта 2018

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

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);
            }
        }

    }
}
1 голос
/ 16 апреля 2013

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

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

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

...