2008-09-18 67 views
39

我的Vista应用程序需要知道用户是以“管理员”身份(提升)还是以标准用户身份(未提升)启动它。我如何在运行时检测?如何检测我的进程是否正在运行UAC提升?

+0

的IsUserAnAdmin功能也可能会有所帮助。 http://msdn.microsoft.com/en-us/library/windows/desktop/bb776463%28v=vs.85%29.aspx – jmnben 2011-10-14 19:11:46

回答

18

下面的C++函数可以做到这一点:

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

对于IsVista函数(以及有关GetElevationType的更多详细信息),请参阅Andrei的博文:http ://www.softblog.com/2008-02/vista-tools/ – 2010-09-02 17:30:31

41

对于我们这些工作在C#,在Windows SDK有一个“UACDemo”应用为“跨技术示例”的一部分。他们发现,如果当前用户是使用此方法管理员:

private bool IsAdministrator 
{ 
    get 
    { 
     WindowsIdentity wi = WindowsIdentity.GetCurrent(); 
     WindowsPrincipal wp = new WindowsPrincipal(wi); 

     return wp.IsInRole(WindowsBuiltInRole.Administrator); 
    } 
} 

(注:我重构原始代码是一个属性,而不是一个“如果”语句)

+0

问题,这将做域安全吗? (MYDOMAIN \ Administrators)或者这只是本地安全? – mattlant 2008-09-24 07:17:39

3

我不认为抬高类型是你想要的答案。你只是想知道它是否升高。当您调用GetTokenInformation时,请使用TokenElevation而不是TokenElevationType。如果结构返回正值,则用户是admin。如果为零,则用户为正常高程。

这里是一个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; 
0

这里是一个VB6实施检查的,如果(当前)工艺升高

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 
相关问题