Meine Vista-Anwendung muss wissen, ob der Benutzer sie "als Administrator" (erhöht) oder als Standardbenutzer (nicht erhöht) gestartet hat. Wie kann ich das zur Laufzeit feststellen?Wie kann ich erkennen, ob mein Prozess UAC-erhöht ausgeführt wird oder nicht?
Antwort
Die folgende C++ Funktion kann das tun:
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;
}
Die IsVista-Funktion (und weitere Details zu GetElevationType) finden Sie in Andreis Blogpost: http : //www.softblog.com/2008-02/vista-tools/ –
Für diejenigen von uns in C# arbeiten, in dem Windows SDK gibt es eine "UACDemo" ist die Anwendung als Teil der "Cross Technology Samples". Sie finden, wenn der aktuelle Benutzer ein Administrator mit dieser Methode ist:
private bool IsAdministrator
{
get
{
WindowsIdentity wi = WindowsIdentity.GetCurrent();
WindowsPrincipal wp = new WindowsPrincipal(wi);
return wp.IsInRole(WindowsBuiltInRole.Administrator);
}
}
(Anmerkung: Ich habe den ursprünglichen Code Refactoring eine Eigenschaft zu sein, anstatt einer „if“ Anweisung)
Frage, wird dies Domänensicherheit tun? (MYDOMAIN \ Administrators) Oder ist dies nur die lokale Sicherheit? – mattlant
WindowsBuiltInRole.Administrator ist die lokale Administratorgruppe – Ryan
Wenn Ihr Domänenaccount ein lokaler Administrator für diesen Computer oder ein Domänenadministrator ist - er wird standardmäßig in dieser lokalen Gruppe afaik sein. –
Ich glaube nicht, Höhen Typ ist die Antwort, die Sie wollen. Sie möchten nur wissen, ob es erhöht ist. Verwenden Sie TokenElevation anstelle von TokenElevationType, wenn Sie GetTokenInformation aufrufen. Wenn die Struktur einen positiven Wert zurückgibt, ist der Benutzer admin. Wenn Null, ist der Benutzer normale Höhe.
Hier ist eine Delphi-Lösung:
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;
hier eine VB6 Implementierung eines Schecks ist, wenn ein (Strom) Prozess
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
Die IsUserAnAdmin Funktion auch hilfreich erhöht ist sein könnte. http://msdn.microsoft.com/en-us/library/windows/desktop/bb776463%28v=vs.85%29.aspx – jmnben