Comment puis-je détecter si mon processus exécute UAC-élevé ou non?

Mon application Vista doit savoir si l’utilisateur l’a lancée “en tant qu’administrateur” (élevée) ou en tant qu’utilisateur standard (non élevé). Comment puis-je le détecter au moment de l’exécution?

Pour ceux d’entre nous qui travaillent en C #, dans le SDK Windows, il existe une application “UACDemo” dans le cadre des “exemples de technologie croisée”. Ils trouvent si l’utilisateur actuel est un administrateur utilisant cette méthode:

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

(Remarque: j’ai modifié le code d’origine pour en faire une propriété, plutôt qu’une instruction “if”)

La fonction C ++ suivante peut faire cela:

 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; } 

Je ne pense pas que le type d’élévation soit la réponse que vous voulez. Vous voulez juste savoir si elle est élevée. Utilisez TokenElevation au lieu de TokenElevationType lorsque vous appelez GetTokenInformation. Si la structure renvoie une valeur positive, l’utilisateur est admin. Si la valeur est zéro, l’utilisateur est en élévation normale.

Voici une solution Delphi:

 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; 

Voici une implémentation VB6 d’une vérification si un processus (actuel) est élevé

 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.dll" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long Private Declare Function GetTokenInformation Lib "advapi32.dll" (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) Then If GetTokenInformation(hToken, TokenElevation, dwIsElevated, 4, dwLength) Then IsElevated = (dwIsElevated <> 0) End If Call CloseHandle(hToken) End If End Function