WPF开发之以管理员身份运行

管理员运行

注意

如果应用没有使用管理员身份运行,会导致应用更新被阻拦,无法更新。

步骤

1.打开项目的属性

2.选择“安全性”,勾选启用ClickOnce安全设置

3.然后会在Properties里自动生成 app.manifest

img

打开app.manifest中修改为如下配置

1
2
3
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
</requestedPrivileges>

可用设置

1
2
3
<requestedExecutionLevel  level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />

4.如果现在直接运行会报错

所以要在之前的属性里取消勾选启用ClickOnce安全设置

现在运行程序就会要求以管理员身份运行了。

注意

尽管程序的默认用户账户控制是asInvoker,在以管理员身份运行的vs里对其他程序的调用也会以管理员身份(以当前调用权限运行)。

代码形式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Reflection;
using System.Security.Principal;
using System.Threading;
using System.Windows;
using SchoolClient.Utils;
using SchoolClient.Wins;

namespace SchoolClient
{
public partial class MyApp : Application
{
[STAThread]
private static void Main()

{
new MyApp();
}

public MyApp()
{
/**
* 当前用户是管理员的时候,直接启动应用程序
* 如果不是管理员,则使用启动对象启动程序,以确保使用管理员身份运行
*/
//获得当前登录的Windows用户标示
WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
//判断当前登录用户是否为管理员
if (principal.IsInRole(WindowsBuiltInRole.Administrator))
{
//如果是管理员,则直接运行
Run(new LoginWindow());
}
else
{
//创建启动对象
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.UseShellExecute = true;
startInfo.WorkingDirectory = Environment.CurrentDirectory;
startInfo.FileName = Assembly.GetExecutingAssembly().Location;
//设置启动动作,确保以管理员身份运行
startInfo.Verb = "runas";
try
{
System.Diagnostics.Process.Start(startInfo);
}
catch
{
return;
}
//退出
Application.Current.Shutdown();
}
}
}
}

判断程序是否以管理员运行

1
2
3
4
5
6
7
using System.Security.Principal;
public bool IsAdministrator()
{
WindowsIdentity current = WindowsIdentity.GetCurrent();
WindowsPrincipal windowsPrincipal = new WindowsPrincipal(current);
return windowsPrincipal.IsInRole(WindowsBuiltInRole.Administrator);
}

注册表写入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#region 开机自启动写入注册表

private void RunAtStart()
{
var starupPath = GetType().Assembly.Location;
try
{
var fileName = starupPath;
var shortFileName = fileName.Substring(fileName.LastIndexOf('\\') + 1);
//打开子键节点
var myReg = Registry.LocalMachine.OpenSubKey(
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", RegistryKeyPermissionCheck.ReadWriteSubTree,
RegistryRights.FullControl);
if (myReg == null)
{
//如果子键节点不存在,则创建之
myReg = Registry.LocalMachine.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
}
if (myReg != null && myReg.GetValue(shortFileName) != null)
{
//在注册表中设置自启动程序
myReg.DeleteValue(shortFileName);
myReg.SetValue(shortFileName, fileName);
LogHelper.WriteLog(typeof(MainWindow), "设置自启动程序操作成功");
}
else if (myReg != null && myReg.GetValue(shortFileName) == null)
{
myReg.SetValue(shortFileName, fileName);
LogHelper.WriteLog(typeof(MainWindow), "设置自启动程序操作成功");
}
}
catch
{
LogHelper.WriteLog(typeof(MainWindow),"写注册表操作发生错误");
}
}

#endregion