【问题标题】:How can I tell if my process is running as Administrator?如何判断我的进程是否以管理员身份运行?
【发布时间】:2010-10-05 06:56:37
【问题描述】:

我想在进程以管理员身份运行时显示一些额外的 UI 元素,而不是在以管理员身份运行时显示一些额外的 UI 元素,类似于 Visual Studio 2008 在以管理员身份运行时在其标题栏中显示“管理员”的方式。我怎么知道?

【问题讨论】:

标签: c# .net process privileges


【解决方案1】:

技术上,如果要查看成员是否为本地管理员账号,那么可以通过WindowsIdentity class上的User property获取当前用户的security identifier (SID),比如所以(静态GetCurrent method获取当前Windows用户):

WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent();

string sid = windowsIdentity.User.ToString();

User 属性返回 has a number of predefined values for various groups and users 的用户的 SID。

然后你会检查the SID has the following pattern, indicating it is the local administrator account (which is a well-known SID):

S-1-5-{其他 SID 部件}-500

或者,如果您不想解析字符串,可以使用SecurityIdentifier 类:

// Get the built-in administrator account.
var sid = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, 
    null);

// Compare to the current user.
bool isBuiltInAdmin = (windowsIdentity.User == sid);

但是,我怀疑您真正想知道的是当前用户是否是本地计算机的管理员的成员。您可以使用WellKnownSidTypeBuiltinAdministratorsSid 获取此SID:

// Get the SID of the admin group on the local machine.
var localAdminGroupSid = new SecurityIdentifier(
    WellKnownSidType.BuiltinAdministratorsSid, null);

然后您可以检查用户的WindowsIdentity 上的Groups property,以查看该用户是否是本地管理员组的成员,如下所示:

bool isLocalAdmin = windowsIdentity.Groups.
    Select(g => (SecurityIdentifier) g.Translate(typeof(SecurityIdentifier))).
    Any(s => s == localAdminGroupSid);

【讨论】:

  • 这是否检查当前用户是否是管理员或进程是否以管理员身份运行?不是管理员的用户仍然可以通过右键单击进程并选择“以管理员身份运行”来以管理员身份运行该进程。
  • @JanTacci 如果用户右键单击并选择以管理员身份运行,则进程以从显示的 UAC 对话框中选择的管理员组中的用户身份运行,该进程不会在那时的登录用户。
  • 作为管理员和以管理员身份运行应用程序是两件不同的事情。即使我是管理员,我仍然可以在没有权限的情况下运行应用程序,这在我的情况下会给我带来问题。
  • 当进程在 UAC 下运行时,不足以确定用户是否是管理员 - i.imgur.com/6sCZ2b2.png - 但是它确实回答了 OP 关于是否以管理员身份运行的原始问题。把这个放在这里是为了那些可能会寻找一个关于如何无条件检测用户是否是管理员的好答案的人(我在找什么)。
【解决方案2】:

我认为这是一个很好的简单机制。

using System.Security.Principal;

WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
bool isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);

【讨论】:

    【解决方案3】:

    我觉得根据上面 casperOne 的回答,我在尝试使用 WellKnownSidType.BuiltinAdministratorsSid 时遇到的困难很重要。根据WellKnownSiDType MSDN,BuiltinAdministratorsSid “表示与管理员帐户匹配的 SID”。所以我希望 casperOne 的代码能够工作,并猜测它可能在某些环境中起作用。不幸的是,它在我的带有 .NET 2.0(遗留代码)的 Windows 2003 上没有。它实际上返回了 S-1-5-32-544,根据this article,它是管理员的 sid。因此,比较对我来说失败了。我将不得不自己对以“S-1-5-21”开头的字符串进行比较(即使上面引用的博客没有,kb 243330 表示包含“21”)并以“500”结尾。

    【讨论】:

      【解决方案4】:

      这是一个单一的班轮。

      using System.Security.Principal;
      
      static bool IsElevated => new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
      

      【讨论】:

      • 如何为 other_process.exe 而不是当前应用执行此操作?
      【解决方案5】:

      我使用简单的 try catch 语句在 "C:\Windows\" 文件夹中创建一个随机文件。如果出现错误,应用程序正在以正常权限运行,否则以管理员权限运行。

              try
              {
                  File.Create(string.Format(@"C:\Windows\{0}.txt", new Guid()), 0, FileOptions.DeleteOnClose);
                  // Do as admin
              }
              catch
              {
                  // Do as default
              }
      

      【讨论】:

      • 如果 UAC 被禁用/设置为最低级别,这将成功
      • 对非异常行为使用异常是一种反模式。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-31
      • 1970-01-01
      • 1970-01-01
      • 2013-05-31
      • 2014-04-26
      相关资源
      最近更新 更多