8

当用户从我的应用程序中保存文件时,他们目前无法保存到受限位置(如 C:)。我认为这是一个很好的限制,但我想提供一个 UAC 提示来提升权限并允许用户在受限区域中保存。

我已经看到很多关于这个主题的答案,这些答案涉及使用“runas”生成一个具有提升权限的新进程。此外,这似乎可以通过冒充另一个用户来完成。据我了解,这两种方法都需要用户提供用户凭据。

我想要做的基本上就是 Windows 本身所做的。当您尝试在 Windows 7 中将文件复制到 C:\ 时(假设您已将 UAC 设置为其默认级别),您会收到以下提示:

UAC 提示

一旦您单击带有 UAC 防护罩的 Continue 按钮,该文件将被复制到 C:\,而不会提示您输入凭据(假设您以管理员权限登录)。

如何在我的应用程序中为管理员用户复制此行为?他们不应该冒充任何其他用户,因为他们已经拥有管理员权限。任何人都可以提供有关 Windows 在此过程中执行的操作的详细信息吗?他们是否生成了具有提升权限的新 explorer.exe 进程?

4

3 回答 3

6

您需要做 Windows 所做的事情。并生成一个新进程,该进程将以提升的权限运行。这里没有捷径。进程启动时分配的令牌决定了进程拥有什么权限。该过程开始后无法更改该令牌。如果你需要提升,你需要一个新的过程。

我已经看到很多关于这个主题的答案,这些答案涉及使用“runas”生成一个具有提升权限的新进程。此外,这似乎可以通过冒充另一个用户来完成。据我了解,这两种方法都需要用户提供用户凭据。

不,事实并非如此。如果当前用户不是管理员,则 UAC 对话框将提示输入具有管理员权限的用户的新凭据。这就是跨肩UAC 对话。另一方面,如果当前用户是管理员,那么他们只会获得同意对话框。这是安全桌面上显示的对话框,只要求您单击继续。

Windows 组件可以做而您不能做的一件事是在不向您显示同意对话框的情况下启动提升的进程。这仅在 Windows 7 上发生(不在 Vista 上),并且仅当您在 Windows 7 中添加的新默认设置中具有 UAC 设置时。这就是资源管理器能够显示问题中包含的对话框然后开始的方式在不显示同意 UAC 对话框的情况下进行复制的提升过程。只有 Windows 组件被授予该能力。

但最重要的是,您需要启动一个运行提升的新进程。使用runas动词是规范的做法。

于 2012-05-24T18:47:17.437 回答
6

编程提升特权/UAC

以超过要求的权限运行应用程序是违反最小权限原则的,并且可能存在潜在的安全漏洞。为了保护这一点,Windows Vista 引入了用户帐户控制 (UAC),通过以降低的权限(作为普通用户)运行应用程序来保护操作系统,即使当前用户以管理员身份登录。越来越多的 XP/2K 用户也使用普通用户帐户进行日常使用。首先阅读 UAC Demystified 以全面了解 UAC。

开发人员容易犯两个常见错误:

  • 请求最终用户以管理员权限运行应用程序,即使这不是必需的,大多数情况下是因为糟糕的设计实践。这些应用程序要么吓跑最终用户,要么可能存在安全漏洞。
  • 不要要求最终用户运行提升的应用程序,而是尝试执行需要管理员权限的操作。这些应用程序只是在 Windows Vista 或 Windows XP/2K 普通用户帐户下中断。

可下载的示例代码演示了如何对提升的权限/UAC 进行编程。提供了 WPF 和 Windows 窗体示例应用程序。为以下场景运行应用程序以查看差异:

  • 普通用户,Windows XP/Windows Vista:显示 UAC 盾牌图标。点击“Save to C:\”会显示“Run As”对话框,要求用户输入管理员密码才能继续;
  • 管理员,禁用 UAC 的 Windows XP/Windows Vista:隐藏 UAC 盾牌图标。点击“Save to C:\”完成,没有任何对话框;
  • 管理员,启用 UAC 的 Windows Vista:显示 UAC 盾牌图标。单击“保存到 C:\”会显示对话框,询问用户是否允许继续。

下载链接

调用提升的执行(首先测试管理员):

private void SaveToRootFolder_Click(object sender, EventArgs e)
    {
        string fileName = @"C:\Test.txt";
        if (App.IsAdmin)
            DoSaveFile(textBox1.Text, textBox2.Text, fileName);
        else
        {
            NameValueCollection parameters = new NameValueCollection();
            parameters.Add("Text1", textBox1.Text);
            parameters.Add("Text2", textBox2.Text);
            parameters.Add("FileName", fileName);
            string result = Program.ElevatedExecute(parameters);
            if (!string.IsNullOrEmpty(result))
                MessageBox.Show(result);
        }
    }

提升执行:

internal static string ElevatedExecute(NameValueCollection parameters)
    {
        string tempFile = Path.GetTempFileName();
        File.WriteAllText(tempFile, ConstructQueryString(parameters));

        try
        {
            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.UseShellExecute = true;
            startInfo.WorkingDirectory = Environment.CurrentDirectory;
            Uri uri = new Uri(Assembly.GetExecutingAssembly().GetName().CodeBase);
            startInfo.FileName = uri.LocalPath;
            startInfo.Arguments = "\"" + tempFile + "\"";
            startInfo.Verb = "runas";
            Process p = Process.Start(startInfo);
            p.WaitForExit();
            return File.ReadAllText(tempFile);
        }
        catch (Win32Exception exception)
        {
            return exception.Message;
        }
        finally
        {
            File.Delete(tempFile);
        }
    }
于 2012-05-24T18:48:23.257 回答
1

一个有限的选项,仅在移动、重命名、复制和删除文件时有用:

SH文件操作

如果您尝试通过此函数执行文件操作,Windows 将向用户提供提升提示。

请注意,这样做有一些缺点:

  • 这仅适用于移动、重命名、复制和删除。以这种方式保存新文件需要保存到临时目录,然后将其移动到所需位置。这不能解决“保存文件对话框”不允许您选择受 UAC 保护的位置作为目标的问题。
  • 如果目标目录不存在(对于移动或复制),SHFileOperation 可以提示用户是否应该创建目标目录。但是,它不会要求提升权限来执行此操作,因此在受 UAC 保护的位置下会失败。解决方法是在临时位置手动创建不存在的目录,然后将它们移动/复制到目标位置。这将提供 UAC 提示。
  • 如果用户在“移动/复制”对话框中选择“跳过”或“取消”,或者用户在 UAC 提示符下选择“否”,您需要制定应急计划。
于 2012-11-27T23:51:44.170 回答