如何使用c#显示文件保存到受限位置的UAC提示?

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

我已经看到很多关于这个主题的答案,涉及使用’runas’产生具有提升权限的新进程。 此外,似乎可以通过冒充其他用户来完成。 据我所知,这两种方法都要求用户提供用户凭据。

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

UAC提示

单击带有UAC屏蔽的“继续”按钮后,该文件将复制到C:\,并且不提示输入凭据(假设您已使用管理员权限登录)。

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

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

我已经看到很多关于这个主题的答案,涉及使用’runas’产生具有提升权限的新进程。 此外,似乎可以通过冒充其他用户来完成。 据我所知,这两种方法都要求用户提供用户凭据。

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

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

但最重要的是,您需要启动一个升级的新流程。 使用runas动词是规范的方法。

编程提升权限/ UAC

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

开发人员往往会犯两个常见的错误:

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

可下载的示例代码演示了如何编写提升权限/ UAC。 提供了WPF和Windows Forms示例应用程序。 运行以下方案的应用程序以查看差异:

  • 普通用户,Windows XP / Windows Vista:显示UAC盾牌图标。 单击“保存到C:\”将显示“运行方式”对话框,要求用户输入管理员密码以继续;
  • 管理员,禁用UAC的Windows XP / Windows Vista:隐藏UAC屏蔽图标。 单击“保存到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); } } 

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

SHFileOperation

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

请注意,这有一些缺点:

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