当需要管理员任务的提升权限时,向按钮添加 UAC 盾牌






4.55/5 (33投票s)
2007年4月22日
2分钟阅读

199045

2565
使用 API 为需要提升权限才能执行管理员任务的按钮添加 UAC 盾牌,并在需要时提升进程权限。

引言
任何并非始终需要管理员权限的应用程序都不应默认以管理员权限运行。 然而,当用户想要执行需要提升权限的任务时,您需要通过显示 Vista 盾牌图标来告知他们这一点。 当单击此图标时,您的应用程序将需要使用管理员权限重新启动。 有兴趣吗? 那么请继续阅读...
创建 VistaSecurity 类
首先,我们需要创建一个 VistaSecurity
类。 在其中,我们需要 SendMessage
API。
[DllImport("user32")]
public static extern UInt32 SendMessage
(IntPtr hWnd, UInt32 msg, UInt32 wParam, UInt32 lParam);
internal const int BCM_FIRST = 0x1600; //Normal button
internal const int BCM_SETSHIELD = (BCM_FIRST + 0x000C); //Elevated button
首先,在添加盾牌之前,我们需要知道进程是否已提升权限,这很容易做到。 要为按钮添加盾牌,请确保该按钮使用 FlatStyle.System
,然后使用 API 发送相应的消息。 重要的 API 函数参数是按钮的句柄和 BCM_SETSHIELD
消息。
static internal bool IsAdmin()
{
WindowsIdentity id = WindowsIdentity.GetCurrent();
WindowsPrincipal p = new WindowsPrincipal(id);
return p.IsInRole(WindowsBuiltInRole.Administrator);
}
static internal void AddShieldToButton(Button b)
{
b.FlatStyle = FlatStyle.System;
SendMessage(b.Handle, BCM_SETSHIELD, 0, 0xFFFFFFFF);
}
然后,我们需要一种在需要时提升进程权限的方法。 我们只需使用 "runas"
Verb 重新启动进程。 除非抛出 System.ComponentModel.Win32Exception
,否则当前未提升权限的进程将退出,因为这表明用户已在 UAC 提示符上单击了“取消”。
internal static void RestartElevated()
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.UseShellExecute = true;
startInfo.WorkingDirectory = Environment.CurrentDirectory;
startInfo.FileName = Application.ExecutablePath;
startInfo.Verb = "runas";
try
{
Process p = Process.Start(startInfo);
}
catch(System.ComponentModel.Win32Exception ex)
{
return;
}
Application.Exit();
}
这就是 VistaSecurity
类的内容。
使用代码
在窗体上,您需要在 InitializeComponent
之后,在构造函数中包含以下代码,它将添加盾牌。
if (!VistaSecurity.IsAdmin())
{
this.Text += " (Standard)"; //Unnecessary
VistaSecurity.AddShieldToButton(buttonGetElevation); //Important
}
else
this.Text += " (Elevated)";
当单击按钮时,我们需要检查您是否有权执行所需操作或提升权限。
if (VistaSecurity.IsAdmin())
{
DoAdminTask();
}
else
{
VistaSecurity.RestartElevated();
}
嗯,这就是如何显示盾牌并获得权限提升!
关注点
对于本演示中的管理员任务,我将文件 VISTA.TXT 添加到所有用户的开始菜单的 \ProgramData\Microsoft\Windows\Start Menu\ 中。 要删除该文件,请再次运行演示(可能需要管理员凭据!)。 “尝试管理员任务”按钮只是尝试创建文件,而无需请求权限提升。
历史
- 07 年 4 月 22 日 - 文章撰写
- 07 年 4 月 24 日 - 通过使用
WindowsBuiltInRole.Administrator
而不是非本地化字符串,管理员帐户的检查适用于非英语版本的 Windows。 在DoAdminTask()
中,MessageBoxes
显示了已完成的操作,增加了更多错误捕获,并使用Environment.SpecialFolder
获取路径。