【问题标题】:How to determine if user is an Administrator, even if non-elevated即使未提升权限,如何确定用户是否为管理员
【发布时间】:2012-04-20 04:07:57
【问题描述】:

在我的 C# 应用程序中,我需要检查当前用户是否是管理员组的成员。它需要与 Windows XP 和 Windows 7 兼容。

目前,我正在使用以下代码:

bool IsAdministrator
{
    get
    {
        WindowsIdentity identity = WindowsIdentity.GetCurrent();
        WindowsPrincipal principal = new WindowsPrincipal(identity);

        return principal.IsInRole(WindowsBuiltInRole.Administrator);
    }
}

问题在于,如果应用程序在 Windows 7 上以非提升管理员身份打开 UAC 运行,则此方法返回 false。即使应用程序以非提升的管理员身份运行,我如何确定用户是否是管理员?

【问题讨论】:

  • 你为什么想知道?
  • 嗯,首先,知道您是否是管理员可以让您知道您是否可以被提升。
  • @svick:如果用户是管理员组的成员,我需要显示某些 UI 元素。
  • 我同意@svick - 你不应该这样做。你想要权限?尝试提升。不要假设用户将始终以未提升的管理员身份运行。作为标准用户运行并使用不同的管理员帐户进行升级是可接受的用法。顺其自然,无论用户如何工作,都让 UAC 机制完成其工作。

标签: c# .net windows-7 uac


【解决方案1】:

有一个 Win32 API GetTokenInformation 可用于检查当前令牌。如果返回的令牌是拆分令牌,则可能是在非提升模式下运行的管理员用户。

GetTokenInformation 有一个输出参数tokenInformation,它采用以下三个值之一:

  • TokenElevationTypeDefault = 1
  • TokenElevationTypeFull = 2
  • TokenElevationTypeLimited = 3

TokenElevantionTypeLimited 值表示用户正在使用具有有限权限的拆分令牌运行。当提升 TokenElevationTypeFull 值时返回。非管理员用户的值为 TokenElevationTypeDefault。

http://www.davidmoore.info/2011/06/20/how-to-check-if-the-current-user-is-an-administrator-even-if-uac-is-on/有一个完整的C#代码示例

【讨论】:

  • 谢谢,这正是我要找的。​​span>
  • 链接已失效。最好将样本放在答案中吗?不确定这里的约定是什么,猜猜如果链接第 3 方,这与许可有关?
  • @TheXenocide 样本应该在答案中(如果版权允许)。自从我写了这篇文章后,我就知道死链接是个问题。
  • @AndersAbel 感谢您的跟进;我只是在这里和那里参与了社区的回答方面的工作,所以很高兴知道“最佳实践”是什么。
【解决方案2】:

如果您是管理员,您可以暂时从代码中禁用 UAC,然后重新启用它。注册表项是

密钥:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System 值:启用LUA 设置为:0 禁用,1 启用

所以你可以做类似的事情

RegistryKey myKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\Policies\\System", true);
myKey.SetValue("EnableLUA", "1", RegistryValueKind.String);

然后检查你的校长。这有点像黑客,但值得一试。

【讨论】:

  • 你的意思是尝试禁用,如果失败了你不是吗?
  • 禁用系统范围的安全设置只是为了进行检查不仅仅是“一种黑客行为”。太可怕了。不要这样做。
  • 我知道这是旧的,但这是一个可怕的想法。更不用说您必须重新启动才能再次读取此设置,因此无论如何它都不起作用。
  • 无论如何,您都需要在您的应用中拥有管理员权限...
【解决方案3】:

我知道这很旧,但我发现以下方法可以在所有系统中正常工作。我需要它在 .net 2 上工作,而其他解决方案(如 WinAPI 和管理对象)在某些版本的 Windows 上失败:

启动一个运行命令net localgroup administrators 的新进程并适当地解析输出。这适用于启用和禁用 UAC 并且不需要提升的进程。

【讨论】:

    【解决方案4】:

    对于任何 VB.NET 的人(我知道你在那里......),这是我从各种来源炮制出来的一个版本,我认为它已经过优化以确定当前用户(包括提升的用户)是否在定义的管理员组、机器或域,启用或不启用 UAC。 (很多感谢这里和其他地方的其他帖子!)

    首先,它使用静态可空布尔值来保持管理员状态,因为虽然基本检查很快,但完整测试可能需要数十秒,所以你只想做一次 - 如果你愿意的话可以帮上忙。

    其次,它在基本测试不正确/错误方面出错,如果用户是 AD 管理的或本地计算机启用了 UAC,通常会出现这种情况。因此,如果它可以确定用户是管理员,它

    第三,您可以在 AuthorizationGroups 中添加或删除您认为合适的条件,但包含的条件涵盖了大多数情况。

    最后,如果出现任何问题,你会得到False;如果你想要一个错误,你可以有一个,但我个人不明白这一点。

    Function IsAdministrator() As Boolean
    
        Static bResult As Boolean? = Nothing
        Try
            If bResult Is Nothing Then
                bResult = New WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator)
                If Not bResult Then
                    Dim oContext As PrincipalContext = Nothing
                    Try 'to get a domain context first ...
                        Domain.GetComputerDomain()
                        oContext = New PrincipalContext(ContextType.Domain)
                    Catch
                        '... if it fails, fall through to a machine context
                    End Try
                    If oContext Is Nothing Then oContext = New PrincipalContext(ContextType.Machine)
                    Dim oPrincipal As UserPrincipal = UserPrincipal.FindByIdentity(oContext, WindowsIdentity.GetCurrent().Name)
                    If oPrincipal IsNot Nothing Then
                        bResult = oPrincipal.GetAuthorizationGroups().Any(Function(p) _
                            p.Sid.IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid) OrElse
                            p.Sid.IsWellKnown(WellKnownSidType.AccountDomainAdminsSid) OrElse
                            p.Sid.IsWellKnown(WellKnownSidType.AccountAdministratorSid) OrElse
                            p.Sid.IsWellKnown(WellKnownSidType.AccountEnterpriseAdminsSid))
                    End If
                End If
            End If
        Catch
            bResult = False
        End Try
        Return bResult.GetValueOrDefault(False)
    End Function
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-27
      • 1970-01-01
      • 2019-07-15
      • 1970-01-01
      • 1970-01-01
      • 2017-09-21
      相关资源
      最近更新 更多