1

我有一个 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 标准用户下运行的,那么该过程会弹出一个对话框,询问管理员的用户名和密码。只有上面以编程方式启动的进程应该以管理员身份运行,主应用程序本身可以保持为标准用户。

4

2 回答 2

3

这不是 UAC 的工作方式。它是基于进程的,当你开始一个新进程时,用户只会得到“请让我弄乱你的机器”提示。程序中嵌入了“我需要用户同意才能弄乱机器,请说是”的正确咒语。你通过这个答案做什么。

以方法为基础的想法死了。对程序员不合理,对用户有意义。用户获胜。

于 2011-08-13T22:01:53.050 回答
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;
}
于 2011-08-13T22:01:43.397 回答