Testing application for Administrative Running Rights

后端 未结 2 1929
一生所求
一生所求 2021-02-15 10:12

I want a sure-shot method to test if the application was run via the UAC box and has full administrative rights. Earlier, I thought of making a folder in C:\\Windows\\ for testi

2条回答
  •  夕颜
    夕颜 (楼主)
    2021-02-15 10:59

    After a fair bit of poking around, I found that the most common solutions to this question return false negatives if the user's UAC is set to anything but Off.

    My solution these days is to do this:

    Imports System.Security.Principal
    Imports System.DirectoryServices.AccountManagement
    Imports System.DirectoryServices.ActiveDirectory
    Imports Microsoft.VisualBasic.ApplicationServices
    
    ''' Checks whether the current user is belongs to any Administrators groups.
    ''' Optional. A flag indicating whether to use GetAuthorizationGroups instead of the - faster - GetGroups. Default=true.
    ''' True if the user belongs to an Administrators group, false otherwise.
    Public Function IsAdministrator(
        Optional ByVal AuthGroups As Boolean = True) 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 'Domain check first
                        Domain.GetComputerDomain()
                        oContext = New PrincipalContext(ContextType.Domain)
                    Catch
                        'Fall through to machine check
                    End Try
                    If oContext Is Nothing Then oContext = New PrincipalContext(ContextType.Machine)
                    'Dim oPrincipal As UserPrincipal = UserPrincipal.FindByIdentity(oContext, WindowsIdentity.GetCurrent().Name) ' Don't use - slow
                    Using oSearchUser As Principal = New UserPrincipal(oContext)
                        oSearchUser.SamAccountName = WindowsIdentity.GetCurrent().Name
                        Using oSearcher As PrincipalSearcher = New PrincipalSearcher(oSearchUser)
                            Using oUser As Principal = oSearcher.FindOne()
                                If oUser IsNot Nothing Then
                                    If AuthGroups Then
                                        bResult = CType(oUser, UserPrincipal).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))
                                    Else
                                        bResult = oUser.GetGroups().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 Using
                        End Using
                    End Using
                End If
            End If
        Catch
            bResult = False
        End Try
        Return bResult.GetValueOrDefault(False)
    End Function
    

    This method is a composite of a few other answers, so I only take credit for packaging it up into a function that will only ever run once and therefore if there is a bit of a delay due to the fall-through, you can probably hide it in start-up.

    The AuthGroups argument gives you a choice of the more thorough, recursive AuthorizationGroups check (default) or the faster Groups check.

提交回复
热议问题