前几天在园子里看到一些关于UAC的文章。我觉得应用程序应该在不减少功能的情况下尽量减少需要管理员权限的操作,即使需要管理员权限来进行某些操作也不要一启动就提示要管理员权限~这样既没有让用户清楚的知道你拿管理员权限做了些什么又可能导致管理员权限被滥用。本文演示的是在 WinForm 和 WPF 应用程序中点击按钮才弹出 UAC 提示要求管理员权限,这样即使用户不提供管理员权限,我们的应用程序仍然可以完成其他普通权限操作。Windows Vista 中有很多地方都是这样,如打开计算机属性(开始 | 右键计算机 | 属性)是不需要管理员权限的,但从这里点击“设备管理器”或“系统保护”等设置就会弹出 UAC 提示,并且这些按钮前会有一个小盾牌。
先演示在 WinForm 中实现上述功能,以下是关键代码,完整代码在文后提供下载
1
// DllImport 以使用 Win32 API
2
[DllImport("user32")]
3
public static extern UInt32 SendMessage(IntPtr hWnd, UInt32 msg, UInt32 wParam, UInt32 lParam);
4
5
/// <summary>
6
/// 构造器
7
/// </summary>
8
public Form1()
9
{
10
InitializeComponent();
11
12
// 当程序没有以管理员权限启动时
13
if (!IsAdmin())
14
{
15
button1.FlatStyle = FlatStyle.System;
16
SendMessage(button1.Handle, 0x160C, 0, 0xFFFFFFFF); // 向按钮发送消息使之加上 UAC 盾牌标志
17
}
18
}
19
20
/// <summary>
21
/// 判断当前是否具有管理员权限
22
/// </summary>
23
private bool IsAdmin()
24
{
25
return new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
26
}
27
28
// 需要管理员权限操作的按钮
29
private void button1_Click(object sender, EventArgs e)
30
{
31
// 将需要管理员权限的操作单独写成一个应用程序在此启动或以管理员权限重新启动当前应用程序
32
// 这里演示的是以管理员权限启动另一个应用程序
33
ProcessStartInfo start = new ProcessStartInfo();
34
start.WorkingDirectory = Environment.CurrentDirectory;
35
start.FileName = "UacValidation.exe"; // 需要以管理员权限启动的文件
36
start.Verb = "runas"; // 这个动词将弹出 UAC 提示
37
try
38
{
39
Process p = Process.Start(start);
40
}
41
catch (System.ComponentModel.Win32Exception ex)
42
{
43
// 如用户在 UAC 提示中点击取消,也就是获取管理员权限失败后的处理
44
MessageBox.Show("未获得管理员权限", "操作失败");
45
}
46
}

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

下面演示的是在 WPF 应用程序中完成上述功能的关键代码
1
/// <summary>
2
/// 构造器
3
/// </summary>
4
public Window1()
5
{
6
InitializeComponent();
7
8
// 当应用程序没有以管理员权限运行时按钮显示盾牌
9
if (!IsAdmin())
10
{
11
// 由于在 WPF 中控件没有Handle,所以需要绘图实现
12
// 先取出盾牌图标
13
Icon icon = new Icon(SystemIcons.Shield, 12, 12);
14
// 绘图
15
Bitmap bitmap = Bitmap.FromHicon(icon.Handle);
16
// 使之显示到界面
17
MemoryStream stream = new MemoryStream();
18
bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
19
ImageBrush imageBrush = new ImageBrush();
20
ImageSourceConverter imageSourceConverter = new ImageSourceConverter();
21
image1.Margin = new Thickness(0, 0, 5, 0);
22
image1.Width = 15;
23
image1.Source = (ImageSource)imageSourceConverter.ConvertFrom(stream);
24
}
25
}
26
27
/// <summary>
28
/// 判断当前是否具有管理员权限
29
/// </summary>
30
private bool IsAdmin()
31
{
32
return new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
33
}
34
35
// 需要管理员权限操作的按钮
36
private void button1_Click(object sender, RoutedEventArgs e)
37
{
38
// 将需要管理员权限的操作单独写成一个应用程序在此启动或以管理员权限重新启动当前应用程序
39
// 这里演示的是以管理员权限启动另一个应用程序
40
ProcessStartInfo start = new ProcessStartInfo();
41
start.WorkingDirectory = Environment.CurrentDirectory;
42
start.FileName = "UacValidation.exe"; // 需要以管理员权限启动的文件
43
start.Verb = "runas"; // 这个动词将弹出 UAC 提示
44
try
45
{
46
Process p = Process.Start(start);
47
}
48
catch (System.ComponentModel.Win32Exception ex)
49
{
50
MessageBox.Show("未获得管理员权限","操作失败");
51
}
52
}

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

标签:
C#
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述