如何确定用户是否是管理员,即使没有提升

时间:2012-04-06 14:53:31

标签: c# .net windows-7 uac

在我的C#应用​​程序中,我需要检查当前用户是否是Administrators组的成员。它需要与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。即使应用程序作为非提升管理员运行,如何确定用户是否为管理员?

4 个答案:

答案 0 :(得分:18)

可以使用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#代码示例

答案 1 :(得分:1)

对于任何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

答案 2 :(得分:0)

我知道这已经过时了,但我发现以下方法可以在所有系统中正常运行。我需要它来处理.net 2和其他解决方案,如WinAPI和管理对象在某些版本的Windows上失败:

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

答案 3 :(得分:-5)

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

键:HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Policies \ System 值:EnableLUA 设置为:0表示禁用,1表示启用

所以你可以做类似

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

然后检查你的校长..这是一种黑客攻击,但值得一试。