Требование повышения не работает для метода в приложении winforms

У меня есть приложение winforms, которое устанавливает другие приложения в цикле. Это работает правильно для учетной записи администратора в Windows 7, но у меня есть серьезные проблемы со стандартной учетной записью - приложению требуется повышение прав для записи в папку "Program Files(x86)".

Поэтому я пытаюсь запросить повышение прав для определенного метода (тот, который запускает установщики) в приложении winforms C#, используя этот код:

[System.Security.Permissions.PrincipalPermission(System.Security.Permissions.SecurityAction.Demand, Role = @"BUILTIN\Administrators")]

После получения ошибки я узнал из Интернета, что перед вызовом метода, который содержит вышеуказанный атрибут, мне нужно написать следующее:

AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);

Я сделал это, и метод все еще выдает следующую ошибку:

Запрос основного разрешения не выполнен.

Пошаговая отладка пропускает строку SetPrincipalPolicy, но, когда она достигает метода с атрибутом Demand, она просто выдает ту же ошибку, как если бы SetPrincipalPolicy никогда не существовало.

Я делаю что-то не так в правильной установке атрибута Demand?

Заранее спасибо.

ПОСЛЕДНЕЕ РЕДАКТИРОВАНИЕ: в соответствии с запросом приведен код, который должен вызывать запрос на повышение прав при автоматической установке приложения (но не работает):

 WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
        bool hasAdministrativeRight = principal.IsInRole(WindowsBuiltInRole.Administrator);
        if (!hasAdministrativeRight)
        {
            ProcessStartInfo psi = new ProcessStartInfo(file);
            psi.WindowStyle = ProcessWindowStyle.Hidden;
            psi.UseShellExecute = true;
            psi.Verb = "runas";

            //psi.CreateNoWindow = true;
            psi.Arguments = modifiers;
            try
            {
                using (Process process = Process.Start(psi))
                {
                    process.WaitForExit();
                    if (process.HasExited)
                        return process.ExitCode;
                }
            }
            catch (Win32Exception wex)
            {

            }
        }

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

2 ответа

Решение

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

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

Третий вариант, который использует Visual Studio, заключается в том, что когда вы делаете что-то, где вам нужны права администратора, вам предлагается перезапустить приложение, а затем оно перезапускает приложение как администратор, и вы можете выполнять задачи. Просто используйте код из второго способа, чтобы запустить свое приложение.

Метод, который вы опубликовали для запуска в качестве администратора, проверит, является ли пользователь администратором, а затем запустит процесс в качестве администратора. Если у пользователя нет прав администратора, приложение даже не запустится. Лучшее решение - всегда пытаться запустить процесс от имени администратора. Затем пользователь получит приглашение UAC с паролем и именем пользователя, которое администратор может заполнить.

public static int RunAsAdmin(string fileName)
{

        ProcessStartInfo psi = new ProcessStartInfo(fileName);
        psi.WindowStyle = ProcessWindowStyle.Hidden;
        psi.UseShellExecute = true;
        psi.Verb = "runas";
        psi.Arguments = modifiers;

        try
        {
            using (Process process = Process.Start(psi))
            {
                process.WaitForExit();
                if (process.HasExited)
                    return process.ExitCode;
            }
        }
        catch (Win32Exception wex)
        {

        }

    return 0;
}

Это просто не то, как работает UAC. Он основан на процессах, когда пользователь запускает новый процесс, пользователь получает сообщение "Пожалуйста, позвольте мне связываться с вашим компьютером". При правильном заклинании "Мне нужно согласие пользователя, чтобы связываться с машиной, пожалуйста, скажите" Да "", встроенный в программу. Что вы делаете этим ответом.

Смерть идее создания метода. Неразумно для программиста, имеет смысл для пользователя. Пользователь побеждает.

Другие вопросы по тегам