Требование повышения не работает для метода в приложении Winforms - PullRequest
0 голосов
/ 14 августа 2011

У меня есть приложение 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 никогда не существовало.

AmЧто-то не так в настройке атрибута 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 ]

3 голосов
/ 14 августа 2011

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

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

1 голос
/ 14 августа 2011

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

Если вы запускаете 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;
}
...