Vista 和 Windows 操作系统为了加强安全增加了 UAC(用户账户控制) 的机制如果 UAC 被打开用户即使是以管理员权限登录其应用程序默认情况下也无法对系统目录系统注册表等可能影响系统运行的设置进行写操作这个机制大大增强了系统的安全性但对应用程序开发者来说我们不能强迫用户去关闭UAC但有时我们开发的应用程序又需要以 Administrator 的方式运行即 Win 中 以 as administrator 方式运行那么我们怎么来实现这样的功能呢?
我们在 win
下运行一些安装程序时
会发现首先弹出一个对话框
让用户确认是否同意允许这个程序改变你的计算机配置
但我们编写的应用程序默认是不会弹出这个提示的
也无法以管理员权限运行
本文介绍了 C# 程序如何设置来提示用户以管理员权限运行
首先在项目中增加一个 Application Manifest File
默认的配置如下
<?xml version="
" encoding="utf
"?>
<asmv
:assemblymanifestVersion="
"xmlns="urn:schemas
microsoft
com:asm
v
"
xmlns:asmv
="urn:schemas
microsoft
com:asm
v
"xmlns:asmv
="urn:schemas
microsoft
com:asm
v
"
xmlns:xsi="
<assemblyIdentityversion="
"name="MyApplication
app"/>
<trustInfoxmlns="urn:schemas
microsoft
com:asm
v
">
<security>
<requestedPrivilegesxmlns="urn:schemas
microsoft
com:asm
v
">
<!
UAC Manifest Options
If you want to change the Windows User Account Control level replace the
requestedExecutionLevel node with one of the following
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
If you want to utilize File and Registry Virtualization for backward
compatibility then delete the requestedExecutionLevel node
>
<requestedExecutionLevellevel="asInvoker"uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</asmv
:assembly>
我们可以看到这个配置中有一个 requestedExecutionLevel 项这个项用于配置当前应用请求的执行权限级别这个项有个值可供选择如下表所示
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 mixedmode 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
asInvoker : 如果选这个应用程序就是以当前的权限运行
highestAvailable: 这个是以当前用户可以获得的最高权限运行
requireAdministrator: 这个是仅以系统管理员权限运行
默认情况下是 asInvoker
highestAvailable 和 requireAdministrator 这两个选项都可以提示用户获取系统管理员权限那么这两个选项的区别在哪里呢?
他们的区别在于如果我们不是以管理员帐号登录那么如果应用程序设置为 requireAdministrator 那么应用程序就直接运行失败无法启动而如果设置为 highestAvailable则应用程序可以运行成功但是是以当前帐号的权限运行而不是系统管理员权限运行如果我们希望程序在非管理员帐号登录时也可以运行(这种情况下应该某些功能受限制) 那么建议采用 highestAvailable 来配置
关于requestedExecutionLevel 设置的权威文档请参考下面链接
Create and Embed an Application Manifest (UAC)
下面是修改后的配置文件
<?xml version="
" encoding="utf
"?>
<asmv
:assemblymanifestVersion="
"xmlns="urn:schemas
microsoft
com:asm
v
"
xmlns:asmv
="urn:schemas
microsoft
com:asm
v
"xmlns:asmv
="urn:schemas
microsoft
com:asm
v
"
xmlns:xsi="
<assemblyIdentityversion="
"name="MyApplication
app"/>
<trustInfoxmlns="urn:schemas
microsoft
com:asm
v
">
<security>
<requestedPrivilegesxmlns="urn:schemas
microsoft
com:asm
v
">
<!
UAC Manifest Options
If you want to change the Windows User Account Control level replace the
requestedExecutionLevel node with one of the following
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
If you want to utilize File and Registry Virtualization for backward
compatibility then delete the requestedExecutionLevel node
>
<requestedExecutionLevellevel="requireAdministrator"uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</asmv
:assembly>
配置文件修改后我们运行应用程序就会首先弹出这样一个提示框点 Yes 后程序才可以继续运行并且获得系统管理员的权限
下面再来看看程序如何知道当前运行在系统管理员权限还是非系统管理员权限
using System
Security
PrincipalpublicstaticboolIsAdministrator()
{
WindowsIdentity identity = WindowsIdentity
GetCurrent();
WindowsPrincipal principal =newWindowsPrincipal(identity);
returnprincipal
IsInRole(WindowsBuiltInRole
Administrator);
}
这段代码可以用于判断当前程序是否运行在系统管理员权限下如果配置为 asInvoker在win 下这个函数会返回 false 如果是 requireAdministrator 则返回 true