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?
Asked
Active
Viewed 1.2k times
42
-
The IsUserAnAdmin function might also be helpful. http://msdn.microsoft.com/en-us/library/windows/desktop/bb776463%28v=vs.85%29.aspx – moltenform Oct 14 '11 at 19:11
4 Answers
41
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)

Adrian Clark
- 12,449
- 5
- 36
- 42
-
Question, will this do domain security? (MYDOMAIN\Administrators) Or is this the local security only? – mattlant Sep 24 '08 at 07:17
-
-
2If your domain account is a local administrator for that machine, or a domain administrator - it will be in that local group by default, afaik. – Oskar Duveborn Feb 03 '09 at 23:11
-
1The thing is the user might be an admin but may still run the app in non-admin mode (by default it's not). Does the WindowsBuildInRole.Administrator can catch that ? – David Brunelle Jul 16 '12 at 21:03
-
1@David Brunelle - It works when the program is run, but be warned that results can be unpredictable when debugging from within VS. I ran into a bump with this until I discovered that the debugger was still running the program as a non-elevated user even when IsInRole(WindowsBuiltInRole.Administrator) returned true. Worked like a charm outside of the debugger. – Shannon Cook May 23 '13 at 01:03
-
@abatishchev, that depends on what you mean by "better". Your code is shorter and more terse, but some would say less readable. – Michael Richardson Jan 07 '14 at 16:05
-
2+1 for referencing the original source of the code. I've seen these lines posted everywhere, but this is the only post to give the reference. – Michael Richardson Jan 07 '14 at 18:30
20
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;
}

Cody Gray - on strike
- 239,200
- 50
- 490
- 574

Andrei Belogortseff
- 1,861
- 3
- 18
- 26
-
For the IsVista function (and more details on GetElevationType), see Andrei's blog post: http://www.softblog.com/2008-02/vista-tools/ – Bradley Grainger Sep 02 '10 at 17:30
4
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;

Guy Glirbas
- 73
- 4
1
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

wqw
- 11,771
- 1
- 33
- 41