【题外话】

Vista 和 Windows 7 操作系统为了巩固安全,扩充了 UAC(用户账户调整)
的建制,借使 UAC
被张开,用户正是是以管理人权限登入,其应用程序暗中同意情形下也无计可施对系统目录,系统注册表等恐怕影响系统运转的安装开始展览写操作。那些机制大大压实了系统的安全性,但对应用程序开采者来讲,我们无法迫使用户去关闭UAC,但不经常大家付出的应用程序又必要以
Administrator 的艺术运转,即 Win7 中 以 as administrator
格局运转,那么大家怎么来落到实处如此的功力吗?

Vista 和 Windows 7 操作系统为了坚实平安,扩张了 UAC(用户账户调整)
的编写制定,尽管 UAC
被展开,用户正是是以管理人权限登入,其应用程序暗许意况下也力不能支对系统目录,系统注册表等可能影响系统运作的安装进行写操作。这么些机制大大做实了系统的安全性,但对应用程序开拓者来讲,大家不能够强迫用户去关闭UAC,但有时大家开垦的应用程序又必要以
Administrator 的艺术运营,即 Win7 中 以 as administrator
情势运转,那么大家怎么来促成如此的意义吗?

从Vista初叶,由于扩大了UAC(用户账户调节,User Account
Control)功能,使得管理员用户平日不再持有能操纵全部机能的管理人权限了,所以在调用相当多相比较重要的听从时供给升级权限来贯彻。有时候写的次第必要调用这种权力,那么大概正是分为运维前就升高以及运维后再进步二种,在这里整理如下。

 

 

 

小编们在 win7
下运作一些安装程序时,会意识首先弹出三个会话框,让用户确认是或不是允许允许那一个顺序改动您的管理器配置,但大家编辑的应用程序默许是不会弹出那么些提示的,也力所不及以管理人权限运维。本文介绍了
C# 程序怎么着设置来提醒用户以管理员权限运营。

大家在 win7
下运转一些安装程序时,会发掘首先弹出叁个对话框,让用户确认是否允许允许那一个顺序改造您的微管理器配置,但大家编辑的应用程序暗许是不会弹出那么些提醒的,也无法以管理人权限运转。本文介绍了
C# 程序怎样设置来唤起用户以管理人权限运营。

必赢登陆,【小说索引】

率先在品种中加进贰个 Application Manifest File

首先在类型中加进贰个 Application Manifest File

  1. 程序运维前提高权限
  2. 程序运转后升高权限
  3. 先后中剖断当前权限

 

 

 

必赢登陆 1

必赢登陆 1

【一、程序运行前进步权限】

 

 

若果全体程序都亟需动用管理员权限的话(乃至主界面上展现的原委都亟待管理员权限才行),那么能够让程序一运转时就进步助理馆员权限,仿佛同大多数的安装程序同样。程序运转时升高权力常常选拔设置manifest文件的措施,能够在档期的顺序中加多“应用程序清单文件”,增加达成后会生成如下图所示的二个文本。除了那个之外,也足以经过选择连串性质,然后步入“安全性”选项卡,然后采用“启用
ClickOnce
安全设置”后也会在类型的“Properties”目录下生成app.manifest文件。

暗中认可的布局如下:

暗许的配置如下:

必赢登陆 3

<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" 

xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" 

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <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 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.
        -->
        <requestedExecutionLevel level="asInvoker" uiAccess="false" />
      </requestedPrivileges>
    </security>
  </trustInfo>
</asmv1:assembly>
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" 

xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" 

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <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 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.
        -->
        <requestedExecutionLevel level="asInvoker" uiAccess="false" />
      </requestedPrivileges>
    </security>
  </trustInfo>
</asmv1:assembly>

在批注中很明朗的认证了一旦要在先后中假若需求越来越高的权能须要修改哪一部分,可是那么些惊叹,这段注释并不曾表达应该修改成哪一类艺术。

 

 

http://blogs.msdn.com/b/winsdk/archive/2010/05/31/dealing-with-administrator-and-standard-user-s-context.aspx寻找到了那二者的分别,分裂如下:

大家得以旁观那么些布局中有叁个 requestedExecutionLevel
项,那一个项用于配置当前利用央求的执行权限等级。那些项有3个值可供选用,如下表所示:

大家能够见见那么些布局中有多少个 requestedExecutionLevel
项,那个项用于配置当前选取诉求的实践权限等级。这一个项有3个值可供选拔,如下表所示:

Possible requested execution level values

 

 

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.

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.
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.

不一样就是,highestAvailable按期下账号能得到到的权限试行,而requireAdministrator则是以装有全部权限的管理人运维。若是当前账户是组织者账户的话,那么双方都是足以的经过进级权限来博取到管理员权限的;而只要当前账户是Guest的话,那么highestAvailable则扬弃升高权限而一直运维,而requireAdministrator则允许输入任何管理员账户的密码来提高权限。

 

 

必赢登陆 4

asInvoker : 若是选这么些,应用程序正是以近期的权限运维。

asInvoker : 假设选那一个,应用程序正是以当下的权能运营。

中间App1使用的是highestAvailable,而App2则利用的是requireAdministrator,能够看到在Administrator用户下都亟需进级权限来运维,在关闭UAC的时候都不必要提高权限。而诸如在Guest下highestAvailable放任了晋级权限,同不时间假若使用requireAdministrator的话则会唤醒类似下图的输入任何管理员账户密码的对话框:

highestAvailable: 那么些是以当下用户能够得到的万丈权力运营。

highestAvailable: 那些是以当下用户能够获取的参天权力运维。

必赢登陆 5

requireAdministrator: 那么些是仅以系统管理员权限运转。

requireAdministrator: 那个是仅以系统管理员权限运转。

于是,如果七个程序必须供给管理员权限技术实行或然才具实施得有意义(例如主分界面上的音讯须要管理员权限本领显得之类的),那么不要紧设置为requireAdministrator,即使使用Guest登录的话也需求升高管理员权限;不然也可设置为highestAvaliable。

 

 

 

默许境况下是 asInvoker。

暗中同意处境下是 asInvoker。

【二、程序运转后提高权限】
假使程序暗中同意不需求权限就会运行大多数效果,只是在分级效用上急需管理员权限的话,那么能够动用程序运转后,当用户须要晋级权限的时候再晋级权限重国民党的新生活运动行程序。由于权力是按进度来的,所以即便急需晋级全体程序的权限,只好以管理员权限创造进度以往再甘休本程序,或许以管理人权限运维别的程序照旧程序通过区别参数来推行不一功能。以管理人权限实行顺序其实非常轻松,只要将ProcessStartInfo对象的Verb属性设置为“runas”就能够,举例如下的代码即能够管理员权限重启本程序。

highestAvailable 和 requireAdministrator
那七个选项都足以提示用户获得系统一管理理员权限。那么那多个挑选的差距在哪个地方呢?

highestAvailable 和 requireAdministrator
那四个选拔都足以提示用户获得系统管理员权限。那么那几个挑选的分别在何地吧?

 1 ProcessStartInfo psi = new ProcessStartInfo();
 2 psi.FileName = Application.ExecutablePath;
 3 psi.Verb = "runas";
 4 
 5 try
 6 {
 7     Process.Start(psi);
 8     Application.Exit();
 9 }
10 catch (Exception eee)
11 {
12     MessageBox.Show(eee.Message);
13 }

他们的区分在于,借使大家不是以管理人帐号登入,那么一旦应用程序设置为
requireAdministrator
,那么应用程序就一贯运维战败,不能够运转。而假使设置为
highestAvailable,则应用程序能够运作成功,但是是以当下帐号的权力运营并非系统管理员权限运行。假使我们盼望程序在非管理员帐号登陆时也得以运营(这种情景下相应有些意义受限制)
,那么提议利用 highestAvailable 来配置。

他们的区分在于,假如我们不是以管理人帐号登入,那么一旦应用程序设置为
requireAdministrator
,那么应用程序就径直运营失利,无法运维。而只要设置为
highestAvailable,则应用程序能够运转成功,然则是以当下帐号的权位运转并非系统管理员权限运转。要是我们愿意程序在非管理员帐号登入时也足以运作(这种情景下应该有个别作用受限制)
,那么建议利用 highestAvailable 来布局。

自然,运维别的程序也是一致的。

至于requestedExecutionLevel 设置的显要文书档案请参见上边链接:

至于requestedExecutionLevel 设置的独尊文档请参照他事他说加以考察上边链接:

而外,大家兴许还需求在那么些按键或菜单上制图UAC盾牌的图标,其实系统已经提供了这么的办法。

Create and Embed an Application Manifest
(UAC)

Create and Embed an Application Manifest
(UAC)

1 [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
2 public static extern int SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, IntPtr lParam);
3 
4 public const UInt32 BCM_SETSHIELD = 0x160C;

 

 

调用的时候如若将按钮的FlatStyle设置为System,然后使用如下的代码就能够了,最终一项要是设为0的话则会收回彰显UAC的盾牌Logo。

上面是修改后的配置文件:

上面是修改后的安插文件:

1 SendMessage(button1.Handle, BCM_SETSHIELD, 0, (IntPtr)1);
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" 

xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"

 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <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 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.
        -->
        <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
      </requestedPrivileges>
    </security>
  </trustInfo>
</asmv1:assembly>

配置文件修改后,我们运行应用程序,就会首先弹出这样一个提示框,点 Yes 后,程序才可以继续运行,并且获得系统管理员的权限。
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" 

xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"

 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <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 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.
        -->
        <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
      </requestedPrivileges>
    </security>
  </trustInfo>
</asmv1:assembly>

配置文件修改后,我们运行应用程序,就会首先弹出这样一个提示框,点 Yes 后,程序才可以继续运行,并且获得系统管理员的权限。

但是假使要往菜单上大概WPF的Button上绘制UAC盾牌的Logo就没办法这样去做了,然则万幸大家仍是能够取获得系统图标,不厌弃的话能够用.NET自带的System.Drawing.SystemIcons.Shield,其实过多软件用的正是这几个Logo,原图如下(32×32):

必赢登陆 6

必赢登陆 6

必赢登陆 8

 

 

理当如此,也得以由此DllImport的措施从系统中获得系统内置的Logo,个中UAC盾牌的Logo的ID是77,代码如下。

下边再来看看程序如何晓伏贴前运作在系统管理员权限依旧非系统一管理理员权限:

下边再来看看程序如何知道当前运营在系统一管理理员权限照旧非系统管理员权限:

 1 [DllImport("shell32.dll", SetLastError = false)]
 2 public static extern Int32 SHGetStockIconInfo(SHSTOCKICONID siid, SHGSI uFlags, ref SHSTOCKICONINFO psii);
 3 
 4 public enum SHSTOCKICONID : uint
 5 {
 6     SIID_SHIELD = 77
 7 }
 8 
 9 [Flags]
10 public enum SHGSI : uint
11 {
12     SHGSI_ICON = 0x000000100,
13     SHGSI_SMALLICON = 0x000000001
14 }
15 
16 [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
17 public struct SHSTOCKICONINFO
18 {
19     public UInt32 cbSize;
20     public IntPtr hIcon;
21     public Int32 iSysIconIndex;
22     public Int32 iIcon;
23 
24     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
25     public string szPath;
26 }

 

 

下一场如下调用就足以将UAC盾牌的Logo设置到菜单上了:

        public static bool IsAdministrator()
        {
            WindowsIdentity identity = WindowsIdentity.GetCurrent();
            WindowsPrincipal principal = new WindowsPrincipal(identity);
            return principal.IsInRole(WindowsBuiltInRole.Administrator);
        }
        public static bool IsAdministrator()
        {
            WindowsIdentity identity = WindowsIdentity.GetCurrent();
            WindowsPrincipal principal = new WindowsPrincipal(identity);
            return principal.IsInRole(WindowsBuiltInRole.Administrator);
        }
1 SHSTOCKICONINFO iconInfo = new SHSTOCKICONINFO();
2 iconInfo.cbSize = (UInt32)System.Runtime.InteropServices.Marshal.SizeOf(iconInfo);
3 SHGetStockIconInfo(SHSTOCKICONID.SIID_SHIELD, SHGSI.SHGSI_ICON | SHGSI.SHGSI_SMALLICON, ref iconInfo);
4 Icon icon = Icon.FromHandle(iconInfo.hIcon);
5 
6 menu.Image = icon.ToBitmap();

 

 

图中menu1是接纳的System.Drawing.SystemIcons.Shield,menu2运用的通过shell32.dll获取到的Logo,button1是行使的SendMessage直接显示的UAC的Logo。

这段代码能够用来判断当前程序是不是运转在系统一管理理员权限下。若是安顿为
asInvoker,在win7 下,那个函数会回去 false ,假若是
requireAdministrator  则赶回 true。

这段代码能够用来判定当前程序是还是不是运维在系统管理员权限下。倘诺布置为
asInvoker,在win7 下,这么些函数会回去 false ,假若是
requireAdministrator  则赶回 true。

必赢登陆 9

本来,照旧应当认清一下种类的本子的,确定保证系统是Vista及其后的版本,不然就没有须求进级权限了。判别是不是是Vista只需求判别系统主版本号是或不是超过等于6就足以了,举个例子以下的代码。

1 Boolean afterVista = (Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version.Major >= 6);

 

【三、程序中判别当前权限】

假如要咬定当前是否以管理人身份运营,只需引用“System.Security.Principal”这些命名空间,然后就可以通过如下的代码获取当前是不是以管理人在运作。

1 WindowsIdentity identity = WindowsIdentity.GetCurrent();
2 WindowsPrincipal principal = new WindowsPrincipal(identity);
3 Boolean isRunasAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);

除去获取当前是或不是是以管理员运转,还足以因而DllImport的方法获得到当下用户是还是不是是管理员用户以及当前进程是或不是升高了权力(只限Vista及以上的本子)等等,详细情况可以见相关链接第22中学的代码。

 

【相关链接】

  1. 编写C#次第让其在Win7
    下以管理员权限运维:http://www.cr173.com/html/11557_1.html
  2. UAC self-elevation
    (CSUACSelfElevation):http://code.msdn.microsoft.com/windowsdesktop/CSUACSelfElevation-644673d3
  3. How to add an uac shield icon to a
    MenuItem:http://www.peschuster.de/2011/12/how-to-add-an-uac-shield-icon-to-a-menuitem/

相关文章