In .NET/C# test if process has administrative privileges

前端 未结 10 2000
天涯浪人
天涯浪人 2020-11-27 03:35

Is there a canonical way to test to see if the process has administrative privileges on a machine?

I\'m going to be starting a long running process, and much later

10条回答
  •  囚心锁ツ
    2020-11-27 04:19

    Starting with Wadih M's code, I've got some additional P/Invoke code to try and handle the case of when UAC is on.

    http://www.davidmoore.info/blog/2011/06/20/how-to-check-if-the-current-user-is-an-administrator-even-if-uac-is-on/

    First, we’ll need some code to support the GetTokenInformation API call:

    [DllImport("advapi32.dll", SetLastError = true)]
    static extern bool GetTokenInformation(IntPtr tokenHandle, TokenInformationClass tokenInformationClass, IntPtr tokenInformation, int tokenInformationLength, out int returnLength);
    
    /// 
    /// Passed to  to specify what
    /// information about the token to return.
    /// 
    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
    }
    
    /// 
    /// The elevation type for a user token.
    /// 
    enum TokenElevationType
    {
        TokenElevationTypeDefault = 1,
        TokenElevationTypeFull,
        TokenElevationTypeLimited
    }
    

    Then, the actual code to detect if the user is an Administrator (returning true if they are, otherwise false).

    var identity = WindowsIdentity.GetCurrent();
    if (identity == null) throw new InvalidOperationException("Couldn't get the current user identity");
    var 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)) return true;
    
    // If we're not running in Vista onwards, we don't have to worry about checking for UAC.
    if (Environment.OSVersion.Platform != PlatformID.Win32NT || Environment.OSVersion.Version.Major < 6)
    {
         // Operating system does not support UAC; skipping elevation check.
         return false;
    }
    
    int tokenInfLength = Marshal.SizeOf(typeof(int));
    IntPtr tokenInformation = Marshal.AllocHGlobal(tokenInfLength);
    
    try
    {
        var token = identity.Token;
        var result = GetTokenInformation(token, TokenInformationClass.TokenElevationType, tokenInformation, tokenInfLength, out tokenInfLength);
    
        if (!result)
        {
            var exception = Marshal.GetExceptionForHR( Marshal.GetHRForLastWin32Error() );
            throw new InvalidOperationException("Couldn't get token information", exception);
        }
    
        var elevationType = (TokenElevationType)Marshal.ReadInt32(tokenInformation);
    
        switch (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;
            default:
                // Unknown token elevation type.
                return false;
         }
    }
    finally
    {    
        if (tokenInformation != IntPtr.Zero) Marshal.FreeHGlobal(tokenInformation);
    }
    

提交回复
热议问题