How can I detect if my process is running UAC-elevated or not?

后端 未结 4 1718
无人及你
无人及你 2020-12-02 18:22

My Vista application needs to know whether the user has launched it \"as administrator\" (elevated) or as a standard user (non-elevated). How can I detect that at run time?

相关标签:
4条回答
  • 2020-12-02 18:45

    For those of us working in C#, in the Windows SDK there is a "UACDemo" application as a part of the "Cross Technology Samples". They find if the current user is an administrator using this method:

    private bool IsAdministrator
    {
        get
        {
            WindowsIdentity wi = WindowsIdentity.GetCurrent();
            WindowsPrincipal wp = new WindowsPrincipal(wi);
    
            return wp.IsInRole(WindowsBuiltInRole.Administrator);
        }
    }
    

    (Note: I refactored the original code to be a property, rather than an "if" statement)

    0 讨论(0)
  • 2020-12-02 18:49

    Here is a VB6 implementation of a check if a (current) process is elevated

    Option Explicit
    
    '--- for OpenProcessToken
    Private Const TOKEN_QUERY                   As Long = &H8
    Private Const TokenElevation                As Long = 20
    
    Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
    Private Declare Function OpenProcessToken Lib "advapi32" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long
    Private Declare Function GetTokenInformation Lib "advapi32" (ByVal TokenHandle As Long, ByVal TokenInformationClass As Long, TokenInformation As Any, ByVal TokenInformationLength As Long, ReturnLength As Long) As Long
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    
    
    Public Function IsElevated(Optional ByVal hProcess As Long) As Boolean
        Dim hToken          As Long
        Dim dwIsElevated    As Long
        Dim dwLength        As Long
    
        If hProcess = 0 Then
            hProcess = GetCurrentProcess()
        End If
        If OpenProcessToken(hProcess, TOKEN_QUERY, hToken) <> 0 Then
            If GetTokenInformation(hToken, TokenElevation, dwIsElevated, 4, dwLength) <> 0 Then
                IsElevated = (dwIsElevated <> 0)
            End If
            Call CloseHandle(hToken)
        End If
    End Function
    
    0 讨论(0)
  • 2020-12-02 18:51

    The following C++ function can do that:

    HRESULT GetElevationType( __out TOKEN_ELEVATION_TYPE * ptet );
    
    /*
    Parameters:
    
    ptet
        [out] Pointer to a variable that receives the elevation type of the current process.
    
        The possible values are:
    
        TokenElevationTypeDefault - This value indicates that either UAC is disabled, 
            or the process is started by a standard user (not a member of the Administrators group).
    
        The following two values can be returned only if both the UAC is enabled
        and the user is a member of the Administrator's group:
    
        TokenElevationTypeFull - the process is running elevated. 
    
        TokenElevationTypeLimited - the process is not running elevated.
    
    Return Values:
    
        If the function succeeds, the return value is S_OK. 
        If the function fails, the return value is E_FAIL. To get extended error information, call GetLastError().
    
    Implementation:
    */
    
    HRESULT GetElevationType( __out TOKEN_ELEVATION_TYPE * ptet )
    {
        if ( !IsVista() )
            return E_FAIL;
    
        HRESULT hResult = E_FAIL; // assume an error occurred
        HANDLE hToken   = NULL;
    
        if ( !::OpenProcessToken( 
                    ::GetCurrentProcess(), 
                    TOKEN_QUERY, 
                    &hToken ) )
        {
            return hResult;
        }
    
        DWORD dwReturnLength = 0;
    
        if ( ::GetTokenInformation(
                    hToken,
                    TokenElevationType,
                    ptet,
                    sizeof( *ptet ),
                    &dwReturnLength ) )
        {
                ASSERT( dwReturnLength == sizeof( *ptet ) );
                hResult = S_OK;
        }
    
        ::CloseHandle( hToken );
    
        return hResult;
    }
    
    0 讨论(0)
  • 2020-12-02 18:59

    I do not think elevation type is the answer you want. You just want to know if it is elevated. Use TokenElevation instead of TokenElevationType when you call GetTokenInformation. If the structure returns a positive value, the user is admin. If zero, the user is normal elevation.

    Here is a Delphi solution:

    function TMyAppInfo.RunningAsAdmin: boolean;
    var
      hToken, hProcess: THandle;
      pTokenInformation: pointer;
      ReturnLength: DWord;
      TokenInformation: TTokenElevation;
    begin
      hProcess := GetCurrentProcess;
      try
        if OpenProcessToken(hProcess, TOKEN_QUERY, hToken) then try
          TokenInformation.TokenIsElevated := 0;
          pTokenInformation := @TokenInformation;
          GetTokenInformation(hToken, TokenElevation, pTokenInformation, sizeof(TokenInformation), ReturnLength);
          result := (TokenInformation.TokenIsElevated > 0);
        finally
          CloseHandle(hToken);
        end;
      except
       result := false;
      end;
    end;
    
    0 讨论(0)
提交回复
热议问题