11

在我的 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。即使应用程序以非提升管理员身份运行,我如何确定用户是否是管理员?

4

4 回答 4

18

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

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

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

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

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

于 2012-04-06T14:59:09.217 回答
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
于 2017-08-18T04:18:50.323 回答
0

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

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

于 2017-01-25T11:56:04.947 回答
-6

如果您是管理员,您可以暂时从代码中禁用 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);

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

于 2012-04-06T15:03:45.917 回答