2008-09-18 38 views
39

Ứng dụng Vista của tôi cần phải biết liệu người dùng đã khởi chạy ứng dụng "làm quản trị viên" (nâng cao) hay là người dùng chuẩn (không nâng cao). Làm thế nào tôi có thể phát hiện ra tại thời gian chạy?Làm thế nào tôi có thể phát hiện nếu quá trình của tôi đang chạy UAC-nâng lên hay không?

+0

Chức năng IsUserAnAdmin cũng có thể hữu ích. http://msdn.microsoft.com/en-us/library/windows/desktop/bb776463%28v=vs.85%29.aspx – jmnben

Trả lời

18

CáC++ chức năng C sau đây có thể làm điều đó:

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

Đối với chức năng IsVista (và biết thêm chi tiết về GetElevationType), hãy xem bài đăng trên blog của Andrei: http : //www.softblog.com/2008-02/vista-tools/ –

41

Đối với những người trong chúng ta làm việc trong C#, trong Windows SDK có một "UACDemo" ứng dụng như một phần của "Mẫu Công nghệ Cross". Họ nhận thấy nếu người dùng hiện nay là một quản trị viên sử dụng phương pháp này:

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

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

(Lưu ý: Tôi refactored mã ban đầu để trở thành một tài sản, chứ không phải là một "nếu" tuyên bố)

+0

Câu hỏi, điều này có làm bảo mật miền không? (MYDOMAIN \ Quản trị viên) Hoặc đây có phải là bảo mật cục bộ không? – mattlant

+0

WindowsBuiltInRole.Administrator là nhóm quản trị cục bộ – Ryan

+2

Nếu tài khoản miền của bạn là quản trị viên cục bộ cho máy đó hoặc quản trị viên tên miền - tài khoản đó sẽ nằm trong nhóm địa phương đó theo mặc định, afaik. –

3

Tôi không nghĩ rằng độ cao loại là câu trả lời bạn muốn. Bạn chỉ muốn biết nếu nó được nâng lên. Sử dụng TokenElevation thay vì TokenElevationType khi bạn gọi GetTokenInformation. Nếu cấu trúc trả về giá trị dương, người dùng là quản trị viên. Nếu không, người dùng là độ cao bình thường.

Dưới đây là một giải pháp 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

Đây là một thực hiện VB6 séc nếu một (hiện hành) quy trình được nâng lên

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 
Các vấn đề liên quan