Testing application for Administrative Running Rights

后端 未结 2 1935
一生所求
一生所求 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:57

    C#:

    using System.Security.Principal;
    
    ...
    
    var identity = WindowsIdentity.GetCurrent();
    var principal = new WindowsPrincipal(identity);
    bool isElevated = principal.IsInRole(WindowsBuiltInRole.Administrator);
    

    VB.Net:

    Imports System.Security.Principal
    
    ...
    
    Dim identity = WindowsIdentity.GetCurrent()
    Dim principal = new WindowsPrincipal(identity)
    Dim isElevated as Boolean = principal.IsInRole(WindowsBuiltInRole.Administrator)
    
    0 讨论(0)
  • 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
    
    ''' <summary>Checks whether the current user is belongs to any Administrators groups.</summary>
    ''' <param name="AuthGroups">Optional. A flag indicating whether to use GetAuthorizationGroups instead of the - faster - GetGroups. Default=true.</param>
    ''' <returns>True if the user belongs to an Administrators group, false otherwise.</returns>
    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.

    0 讨论(0)
提交回复
热议问题