检查用户是否是管理员

时间:2017-08-24 20:37:26

标签: .net vb.net

我正在编写一个Visual Basic .NET桌面应用程序(目前使用的是WinForms和.NET Framework 4.5.1)。

我需要应用程序检测当前Windows用户是否具有系统Administrator角色,但无需用户使用Run as administrator启动应用程序。

  1. 我登录的Windows 10计算机上有Administrator个角色。
  2. enter image description here

    1. 以下代码返回machinename/ian

      Dim CurrUser As WindowsIdentity CurrUser = WindowsIdentity.GetCurrent() MSGBOX(CurrUser.Name)

    2. 但是,当我测试自己是否具有管理员角色时,结果为False,除非我Run as administrator

      MSGBOX(My.User.IsInRole(ApplicationServices.BuiltInRole.Administrator))

    3. 在SO上已经多次询问过类似的问题,但除非我使用Run as Administrator启动应用程序,否则解决方案(都与上述类似)将返回false。

      动机

      • 该应用程序将由安装在
      • 上的计算机上的不同用户使用
      • 我想隐藏一般用户的一组扩展选项,但是可以将它们提供给机器的“所有者”,我将其识别为具有管理员角色的用户
      • 应用程序本身不需要使用提升的权限执行 - 它不应该能够更改用户系统的某些部分。从信任的角度来看,我希望我的用户知道应用程序并不危险,并且没有充分的理由他们不需要Run as administrator

      我正在寻找一种在Windows 10 Home(我认为没有目录服务和Active Directory?)上也能正常运行的解决方案,最好该解决方案也可以在Windows 7上运行。

1 个答案:

答案 0 :(得分:0)

注意:以下用于测试用户是否为管理员的检查不是100%可靠,请参阅"用户帐户控制(UAC)"以下链接部分和参考文献。

以下代码基于C#解决方案found here(由this comment @Damien_The_Unbeliever建议)

Imports System.Runtime.InteropServices
Imports System.Security.Principal

<DllImport("advapi32.dll", SetLastError:=True)>
Private Shared Function GetTokenInformation(tokenHandle As IntPtr, tokenInformationClass As TokenInformationClass, tokenInformation As IntPtr, tokenInformationLength As Integer, ByRef returnLength As Integer) As Boolean
End Function

''' <summary>
''' Passed to <see cref="GetTokenInformation"/> to specify what
''' information about the token to return.
''' </summary>
Private Enum TokenInformationClass
    TokenUser = 1
    TokenGroups
    TokenPrivileges
    TokenOwner
    TokenPrimaryGroup
    TokenDefaultDacl
    TokenSource
    TokenType
    TokenImpersonationLevel
    TokenStatistics
    TokenRestrictedSids
    TokenSessionId
    TokenGroupsAndPrivileges
    TokenSessionReference
    TokenSandBoxInert
    TokenAuditPolicy
    TokenOrigin
    TokenElevationType
    TokenLinkedToken
    TokenElevation
    TokenHasRestrictions
    TokenAccessInformation
    TokenVirtualizationAllowed
    TokenVirtualizationEnabled
    TokenIntegrityLevel
    TokenUiAccess
    TokenMandatoryPolicy
    TokenLogonSid
    MaxTokenInfoClass
End Enum

''' <summary>
''' The elevation type for a user token.
''' </summary>
Private Enum TokenElevationType
    TokenElevationTypeDefault = 1
    TokenElevationTypeFull
    TokenElevationTypeLimited
End Enum




Private Function IsAdmin()
    Dim identity = WindowsIdentity.GetCurrent()
    If identity Is Nothing Then
        Throw New InvalidOperationException("Couldn't get the current user identity")
    End If
    Dim principal = New WindowsPrincipal(identity)

    ' Check if this user has the Administrator role. If they do, return immediately.
    ' If UAC is on, and the process is not elevated, then this will actually return false.
    If principal.IsInRole(WindowsBuiltInRole.Administrator) Then
        Return True
    End If

    ' If we're not running in Vista onwards, we don't have to worry about checking for UAC.
    If Environment.OSVersion.Platform <> PlatformID.Win32NT OrElse Environment.OSVersion.Version.Major < 6 Then
        ' Operating system does not support UAC; skipping elevation check.
        Return False
    End If

    Dim tokenInfLength As Integer = Marshal.SizeOf(GetType(Integer))
    Dim tokenInformation As IntPtr = Marshal.AllocHGlobal(tokenInfLength)

    Try
        Dim token = identity.Token
        Dim result = GetTokenInformation(token, TokenInformationClass.TokenElevationType, tokenInformation, tokenInfLength, tokenInfLength)

        If Not result Then
            Dim exception = Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error())
            Throw New InvalidOperationException("Couldn't get token information", exception)
        End If

        Dim elevationType = DirectCast(Marshal.ReadInt32(tokenInformation), TokenElevationType)

        Select Case elevationType
            Case TokenElevationType.TokenElevationTypeDefault
                ' TokenElevationTypeDefault - User is not using a split token, so they cannot elevate.
                Return False
            Case TokenElevationType.TokenElevationTypeFull
                ' TokenElevationTypeFull - User has a split token, and the process is running elevated. Assuming they're an administrator.
                Return True
            Case TokenElevationType.TokenElevationTypeLimited
                ' TokenElevationTypeLimited - User has a split token, but the process is not running elevated. Assuming they're an administrator.
                Return True
            Case Else
                ' Unknown token elevation type.
                Return False
        End Select
    Finally
        If tokenInformation <> IntPtr.Zero Then
            Marshal.FreeHGlobal(tokenInformation)
        End If
    End Try
End Function