.NET中提升UAC权限的方法总结
【题外话】
从Vista开始,由于增加了UAC(用户账户控制,User Account Control)功能,使得管理员用户平时不再拥有能控制所有功能的管理员权限了,所以在调用很多比较重要的功能时需要提升权限来实现。有时候写的程序需要调用这种权限,那么大概就是分为运行前就提升以及运行后再提升两种,在这里整理如下。
【文章索引】
【一、程序运行前提升权限】
如果整个程序都需要使用管理员权限的话(甚至主界面上显示的内容都需要管理员权限才行),那么可以让程序一运行时就提升管理员权限,就如同大部分的安装程序一样。程序运行时提高权限通常采用设置manifest文件的方式,可以在项目中添加“应用程序清单文件”,添加完成后会生成如下图所示的一个文件。除此之外,也可以通过选择项目属性,然后进入“安全性”选项卡,然后选择“启用 ClickOnce 安全设置”后也会在项目的“Properties”目录下生成app.manifest文件。

在注释中很明确的说明了如果要在程序中如果需要更高的权限需要修改哪部分,不过非常好奇,这段注释并没有说明应该修改成哪种方式。
在http://blogs.msdn.com/b/winsdk/archive/2010/05/31/dealing-with-administrator-and-standard-user-s-context.aspx搜索到了这两者的区别,区别如下:
Possible requested execution level values
|
Value |
Description |
Comment |
|
asInvoker |
The application runs with the same access token as the parent process. |
Recommended for standard user applications. Do refractoring with internal elevation points, as per the guidance provided earlier in this document. |
|
highestAvailable |
The application runs with the highest privileges the current user can obtain. |
Recommended for mixed-mode applications. Plan to refractor the application in a future release. |
|
requireAdministrator |
The application runs only for administrators and requires that the application be launched with the full access token of an administrator. |
Recommended for administrator only applications. Internal elevation points are not needed. The application is already running elevated. |
区别即是,highestAvailable按当前账号能获取到的权限执行,而requireAdministrator则是以具有完整权限的管理员运行。如果当前账户是管理员账户的话,那么两者都是可以的通过提升权限来获取到管理员权限的;而如果当前账户是Guest的话,那么highestAvailable则放弃提升权限而直接运行,而requireAdministrator则允许输入其他管理员账户的密码来提升权限。

其中App1使用的是highestAvailable,而App2则使用的是requireAdministrator,可以看出在Administrator用户下都需要提升权限来运行,在关闭UAC的时候都不需要提升权限。而比如在Guest下highestAvailable放弃了提升权限,同时如果使用requireAdministrator的话则会提示类似下图的输入其他管理员账户密码的对话框:

所以,如果一个程序必须要求管理员权限才能执行或者才能执行得有意义(比如主界面上的信息需要管理员权限才能显示之类的),那么不妨设置为requireAdministrator,即使使用Guest登陆的话也需要提升管理员权限;否则也可设置为highestAvaliable。
【二、程序运行后提升权限】
如果程序默认不需要权限就能运行大部分功能,只是在个别功能上需要管理员权限的话,那么可以采用程序运行后,当用户需要提升权限的时候再提升权限重新运行程序。由于权限是按进程来的,所以如果需要提升整个程序的权限,只能以管理员权限创建进程以后再结束本程序,或者以管理员权限运行其他程序或者程序通过不同参数来执行不同功能。以管理员权限执行程序其实非常简单,只要将ProcessStartInfo对象的Verb属性设置为“runas”即可,例如如下的代码即可以管理员权限重启本程序。
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = Application.ExecutablePath;
psi.Verb = "runas"; try
{
Process.Start(psi);
Application.Exit();
}
catch (Exception eee)
{
MessageBox.Show(eee.Message);
}
当然,运行其他程序也是一样的。
除此之外,我们可能还需要在这个按钮或菜单上绘制UAC盾牌的图标,其实系统已经提供了这样的方法。
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, IntPtr lParam);
public const UInt32 BCM_SETSHIELD = 0x160C;
调用的时候只要将按钮的FlatStyle设置为System,然后采用如下的代码就可以了,最后一项如果设为0的话则会取消显示UAC的盾牌图标。
SendMessage(button1.Handle, BCM_SETSHIELD, , (IntPtr));
不过如果要往菜单上或者WPF的Button上绘制UAC盾牌的图标就没法这样去做了,不过好在我们还可以获取到系统图标,不嫌弃的话可以用.NET自带的System.Drawing.SystemIcons.Shield,其实好多软件用的就是这个图标,原图如下(32×32):

当然,也可以通过DllImport的方式从系统中获取系统内置的图标,其中UAC盾牌的图标的ID是77,代码如下。
[DllImport("shell32.dll", SetLastError = false)]
public static extern Int32 SHGetStockIconInfo(SHSTOCKICONID siid, SHGSI uFlags, ref SHSTOCKICONINFO psii);
public enum SHSTOCKICONID : uint
{
SIID_SHIELD =
}
[Flags]
public enum SHGSI : uint
{
SHGSI_ICON = 0x000000100,
SHGSI_SMALLICON = 0x000000001
}
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SHSTOCKICONINFO
{
public UInt32 cbSize;
public IntPtr hIcon;
public Int32 iSysIconIndex;
public Int32 iIcon;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
public string szPath;
}
然后如下调用就可以将UAC盾牌的图标设置到菜单上了:
SHSTOCKICONINFO iconInfo = new SHSTOCKICONINFO();
iconInfo.cbSize = (UInt32)System.Runtime.InteropServices.Marshal.SizeOf(iconInfo);
SHGetStockIconInfo(SHSTOCKICONID.SIID_SHIELD, SHGSI.SHGSI_ICON | SHGSI.SHGSI_SMALLICON, ref iconInfo);
Icon icon = Icon.FromHandle(iconInfo.hIcon); menu.Image = icon.ToBitmap();
图中menu1是使用的System.Drawing.SystemIcons.Shield,menu2使用的通过shell32.dll获取到的图标,button1是使用的SendMessage直接显示的UAC的图标。

当然,还是应该判断一下系统的版本的,确保系统是Vista及以后的版本,否则就不需要提升权限了。判断是否是Vista只需要判断系统主版本号是否大于等于6就可以了,例如以下的代码。
Boolean afterVista = (Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version.Major >= );
【三、程序中判断当前权限】
如果要判断当前是否以管理员身份运行,只需引用“System.Security.Principal”这个命名空间,然后就可以通过如下的代码获取当前是否以管理员在运行。
WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
Boolean isRunasAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);
除了获取当前是否是以管理员运行,还可以通过DllImport的方式获取到当前用户是否是管理员用户以及当前进程是否提升了权限(仅限Vista及以上的版本)等等,详情可以见相关链接2中的代码。
【相关链接】
- 编写C#程序让其在Win7 下以管理员权限运行:http://www.cr173.com/html/11557_1.html
- UAC self-elevation (CSUACSelfElevation):http://code.msdn.microsoft.com/windowsdesktop/CSUACSelfElevation-644673d3
- How to add an uac shield icon to a MenuItem:http://www.peschuster.de/2011/12/how-to-add-an-uac-shield-icon-to-a-menuitem/
.NET中提升UAC权限的方法总结的更多相关文章
- android中获取root权限的方法以及原理(转)
一. 概述 本文介绍了android中获取root权限的方法以及原理,让大家对android 玩家中常说的“越狱”有一个更深层次的认识. 二. Root 的介绍 1. Root 的目的 可以让我们拥有 ...
- centos7中提升用户权限
提升用户权限我看网上资源有两种方法,一种是修改/etc/sudoers/文件将新增的用户权限提升为和root一样的权限,这种方法不知道怎么回事我没用应用成功,这里我介绍第二种方法,第二种方法是更改/e ...
- UAC权限
.NET中提升UAC权限的方法总结 [题外话] 从Vista开始,由于增加了UAC(用户账户控制,User Account Control)功能,使得管理员用户平时不再拥有能控制所有功能的管理员权 ...
- cocoa中获得root权限的几种方法
目前我所知道的,在cocoa中获得root权限的方法有3种: 1. 通过AuthorizationCopyRights函数 2. 在UI上添加一个锁的样子的控件,然后通过开关这个锁来获取root权限 ...
- 实现在vista和win7中使用管理员权限接收WM_DROPFILES(OnDropFiles())消息的方法(好像XP不支持这个函数)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #pragma once #ifndef WM_COPYGLOBALD ...
- 解决vista和win7在windows服务中交互桌面权限问题:穿透Session 0 隔离
在某国外大型汽车公司BI项目中,有一个子项目,需要通过大屏幕展示销售报表,程序需要自动启动和关闭.开发人员在开发过程中,发现在Win7的service中不能直接操作UI进程,调查过程中,发现如 ...
- 利用PATH环境变量 - 提升linux权限~👻
利用PATH提升linux权限 参考地址:https://www.hackingarticles.in/linux-privilege-escalation-using-path-variable/ ...
- mysql 5.7中的用户权限分配相关解读!
这篇文章主要介绍了MySQL中基本的用户和权限管理方法,包括各个权限所能操作的事务以及操作权限的一些常用命令语句,是MySQL入门学习中的基础知识,需要的朋友可以参考下 一.简介 各大帖子及文章都会讲 ...
- iOS开发中的这些权限,你搞懂了吗?
APP开发避免不开系统权限的问题,如何在APP以更加友好的方式向用户展示系统权限,似乎也是开发过程中值得深思的一件事. 那如何提高APP获取iOS系统权限的通过率呢?有以下几种方式:1.在用户打开AP ...
随机推荐
- AgileEAS.NET SOA 中间件平台.Net Socket通信框架-介绍
一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...
- C# 图片无损压缩
/// <summary> /// 图像缩略图处理 /// </summary> /// <param name="bytes">图像源数据&l ...
- 【CentOS】LAMP
文章需要整合,学习需要归纳,博主把一连四篇的LAMP合并成为一片长篇的大部头,并梳理了一下他们的关系,希望对各位有所帮助 最近一次更新:2016年12月21日21:38:31 本文为博主JerryCh ...
- 【转】《从入门到精通云服务器》第七讲—IAAS、PAAS、SAAS
Saas.Paas.IaaS这三个词,一直困扰众人很久.就拿字面意思来说,分别是:软件即服务,平台即服务,设施即服务.小编表示这个不往深了讲,真心看不懂,还容易弄混淆.今天我们就来扒一扒这三者的深层含 ...
- 苹果手机微信上form表单提交的问题
场景:前端页面请求后端php,返回带form表单dom元素,然后将其追在页面上,返回的html字段中包含表单自动提交的代码,想法是将带有表单自动提交的dom元素追加到页面上,然后表单自动提交到另外一个 ...
- 踏上Salesforce的学习之路(二)
一.添加一个字段到对象中 1.给Merchandise对象添加一个Price字段 先点击右上角姓名旁边的Setup(不管你在哪个页面,点击Setup都能让你快速的回到首页,如下图所示),然后在左侧的Q ...
- wex5中的星星评分
新建一个空白的.w文件,然后在页面上放5个img星星图片 重要的是图片路径不能是绝对路径,要用相对路径,不然js操作的时候会出bug 添加两个label标签(标签随你挑,在这我就用label) 你到时 ...
- Apache InterfaceAudience
InterfaceAudience 类包含三个注解类型,用来被说明被他们注解的类型的潜在的使用范围(audience).@InterfaceAudience.Public: 对所有工程和应用可用@In ...
- SMA、SMB、SMC封装的二极管
以常见的贴片肖特基二极管SS14 SS24 SS34为例,三种管子区别主要在电流上,有三种封装:SMA.SMB.SMC. 从成本和体积来说,优先选用最小尺寸的SMA/DO-214AC封装,其他封装一般 ...
- Swift 3 and OpenGL on Linux and macOS with GLFW
https://solarianprogrammer.com/2016/11/19/swift-opengl-linux-macos-glfw/ Swift 3 and OpenGL on Linux ...