1、通过添加应用程序清单文件:
Vista 和 Windows 7 操作系统为了加强安全,增加了 UAC(用户账户控制) 的机制,如果 UAC 被打开,用户即使是以管理员权限登录,其应用程序默认情况下也无法对系统目录,系统注册表等可能影响系统运行的设置进行写操作。这个机制大大增强了系统的安全性,但对应用程序开发者来说,我们不能强迫用户去关闭UAC,但有时我们开发的应用程序又需要以 Administrator 的方式运行,即 Win7 中 以 as administrator 方式运行,那么我们怎么来实现这样的功能呢?
首先在项目中增加一个 Application Manifest File
默认配置为
<?xml version="1.0" encoding="utf-8"?> <assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"> <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> <security> <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> <!-- UAC 清单选项 如果想要更改 Windows 用户帐户控制级别,请使用 以下节点之一替换 requestedExecutionLevel 节点。n <requestedExecutionLevel level="asInvoker" uiAccess="false" /> <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> <requestedExecutionLevel level="highestAvailable" uiAccess="false" /> 指定 requestedExecutionLevel 元素将禁用文件和注册表虚拟化。 如果你的应用程序需要此虚拟化来实现向后兼容性,则删除此 元素。 --> <requestedExecutionLevel level="asInvoker" uiAccess="false" /> </requestedPrivileges> </security> </trustInfo> <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <application> <!-- 设计此应用程序与其一起工作且已针对此应用程序进行测试的 Windows 版本的列表。取消评论适当的元素, Windows 将自动选择最兼容的环境。 --> <!-- Windows Vista --> <!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />--> <!-- Windows 7 --> <!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />--> <!-- Windows 8 --> <!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />--> <!-- Windows 8.1 --> <!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />--> <!-- Windows 10 --> <!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />--> </application> </compatibility> <!-- 指示该应用程序可以感知 DPI 且 Windows 在 DPI 较高时将不会对其进行 自动缩放。Windows Presentation Foundation (WPF)应用程序自动感知 DPI,无需 选择加入。选择加入此设置的 Windows 窗体应用程序(目标设定为 .NET Framework 4.6 )还应 在其 app.config 中将 "EnableWindowsFormsHighDpiAutoResizing" 设置设置为 "true"。--> <!-- <application xmlns="urn:schemas-microsoft-com:asm.v3"> <windowsSettings> <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware> </windowsSettings> </application> --> <!-- 启用 Windows 公共控件和对话框的主题(Windows XP 和更高版本) --> <!-- <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" /> </dependentAssembly> </dependency> --> </assembly>
我们可以看到这个配置中有一个 requestedExecutionLevel 项,这个项用于配置当前应用请求的执行权限级别。这个项有3个值可供选择,如下表所示:
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. |
asInvoker : 如果选这个,应用程序就是以当前的权限运行。
highestAvailable: 这个是以当前用户可以获得的最高权限运行。
requireAdministrator: 这个是仅以系统管理员权限运行。
默认情况下是 asInvoker。
highestAvailable 和 requireAdministrator 这两个选项都可以提示用户获取系统管理员权限。那么这两个选项的区别在哪里呢?
他们的区别在于,如果我们不是以管理员帐号登录,那么如果应用程序设置为 requireAdministrator ,那么应用程序就直接运行失败,无法启动。而如果设置为 highestAvailable,则应用程序可以运行成功,但是是以当前帐号的权限运行而不是系统管理员权限运行。如果我们希望程序在非管理员帐号登录时也可以运行(这种情况下应该某些功能受限制) ,那么建议采用 highestAvailable 来配置。
如果需要已管理员权限启动程序,则将
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
改为
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
配置文件修改后,我们运行应用程序,就会首先弹出这样一个提示框,点 Yes 后,程序才可以继续运行,并且获得系统管理员的权限。
下面再来看看程序如何知道当前运行在系统管理员权限还是非系统管理员权限:
public static bool IsAdministrator() { WindowsIdentity identity = WindowsIdentity.GetCurrent(); WindowsPrincipal principal = new WindowsPrincipal(identity); return principal.IsInRole(WindowsBuiltInRole.Administrator); }
2、通过 System.Diagnostics.Process.Start() 方式启动:
static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); /** * 当前用户是管理员的时候,直接启动应用程序 * 如果不是管理员,则使用启动对象启动程序,以确保使用管理员身份运行 */ //获得当前登录的Windows用户标示 System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent(); System.Security.Principal.WindowsPrincipal principal = new System.Security.Principal.WindowsPrincipal(identity); //判断当前登录用户是否为管理员 if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator)) { //如果是管理员,则直接运行 Application.Run(new Form1()); } else { //创建启动对象 System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(); startInfo.UseShellExecute = true; startInfo.WorkingDirectory = Environment.CurrentDirectory; startInfo.FileName = Application.ExecutablePath; //设置启动动作,确保以管理员身份运行 startInfo.Verb = "runas"; try { System.Diagnostics.Process.Start(startInfo); } catch { return; } //退出 Application.Exit(); } } }