开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情
程序使用过程中经常遇到需要管理员权限运行才能执行的情况,如操作注册表、系统文件或配置文件等。
以管理员权限运行程序的最简单方式,是右键程序,选择“以管理员权限运行”。
但,如果打开时,默认以系统管理员权限运行,将会很方便。本篇将对几种实现管理员权限运行的方式进行总结,希望足够全。
方法一【ClickOnce生成清单文件】
Visual studio
中,解决方案资源管理器下,右键项目>属性,在安全性
下,勾选启用ClickOnce安全设置
app.manifest
文件会出现在项目名下面的属性
目录中。
双击打开,并找到代码<requestedExecutionLevel level="asInvoker" uiAccess="false" />
,将属性level
的值改为requireAdministrator
文件中对UAC控制(User Account Control)已经进行了说明
修改后保存即可。
权限说明
- asInvoker : 应用程序以当前的权限运行。
- highestAvailable: 以当前用户可以获得的最高权限运行。
- requireAdministrator: 请求以系统管理员权限运行。
- 重新打开项目
属性
>安全性
,将启用ClickOnce安全设置
的勾选取消。
启用ClickOnce安全设置
的情况下: 如果debug启动,程序会提示不可用于VS进程。VS将不能进行安全调试。
如果直接生成,会报错
ClickOnce 不支持请求执行级别“requireAdministrator”。 RegisterUse
因此,需要取消勾选
启用ClickOnce安全设置
。
- 执行 调试>启动,会提示相应权限运行。
即,要管理员权限运行当前程序,需要vs也是管理员权限打开。
- 重新编译生成exe程序,双击运行,会
请求管理员权限
运行。
方法二【直接添加清单文件】
项目下添加项目清单
文件。
- 右键项目>添加>新建项>选择
应用程序清单文件
- 此时在项目下会生成
app.manifest
文件。其内容和修改与上面的设置相同
这样就不用修改启用ClickOnce安全设置
。
方法三【判断程序自身是否管理员权限运行,并使用Process管理员重新启动自身】
通过判断当前运行程序的权限是管理员还是非管理员,决定是否请求管理员权限运行程序。这对于将程序安装到C盘后,需要管理员权限操作,其他盘则不需要管理员权限,会显得比较灵活。
通过修改Program
文件,借助System.Diagnostics.Process.Start()以应用程序进程的方式重新以管理员权限打开程序(只有当前用户为管理员时才会直接运行)。
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//获取当前登陆的windows用户
//获取当前Windows用户的WindowsIdentity对象
System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent();
//创建可以代码访问的windows组成员对象
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 (Exception)
{
return;
}
//退出当前,使用新打开的程序
Application.Exit();
}
//Application.Run(new Form1());
}
}
方法四【修改程序属性的兼容性设置】
直接修改程序文件的属性。
右键exe
文件,属性>兼容性下,设置以管理员身份运行此程序
附:判断程序当前运行是管理员权限还是非管理员权限
public static bool IsAdministrator()
{
WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
附:通过Process.Start()
启动程序时接收命令行或输入参数
上面使用Process.Start()
以管理员方式重新启动自身程序时,没有考虑到Main
入口方法的输入参数的传递问题。借助ProcessStartInfo.Arguments
可以在启动程序时,传入启动参数。
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] Args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//获取当前登陆的windows用户
//获取当前Windows用户的WindowsIdentity对象
WindowsIdentity identity = WindowsIdentity.GetCurrent();
//创建可以代码访问的windows组成员对象
WindowsPrincipal principal = new WindowsPrincipal(identity);
//判断是否为管理员
if (principal.IsInRole(WindowsBuiltInRole.Administrator))
{
//如果是管理员则直接运行
if (Args.Length>0)//判断是否输入参数
{
Application.Run(new Form1(Args));
}
else
{
Application.Run(new Form1());
}
}
else
{
//创建启动对象
//指定启动进程时的信息
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.UseShellExecute = true;
startInfo.WorkingDirectory = Environment.CurrentDirectory;//设置当前工作目录的完全路径
//设置运行文件
startInfo.FileName = Application.ExecutablePath;//获取当前执行文件的路径
//设置启动参数
if (Args.Length>0)
{
//获取或设置启动应用程序时的邮政命令行自变量
startInfo.Arguments = String.Join(" ", Args);
}
//设置启动动作,确保以管理员权限运行
startInfo.Verb = "runas";
try
{
Process.Start(startInfo);
}
catch (Exception)
{
MessageBox.Show("启动失败!");
return;
}
//退出当前,使用新打开的程序
Application.Exit();
}
}
从
ProcessStartInfo.Verb = "runas"
以管理员权限启动进程来说,可以实现管理员权限运行另一个程序,或,启动另一个进程。