2016-11-18 86 views
1

我正在嘗試獲取屬於當前用戶的進程的PID,但我不知道如何檢查進程所有者。如何檢查進程是否屬於當前用戶?

這是我的代碼(用戶的檢查條件丟失):

uses 
    TlHelp32, ...; 

type 
    TCardinalArray = array of Cardinal; 

function GetCurrentUserPIDs(const AProcessName : string) : TCardinalArray; 
var 
    ContinueLoop: boolean; 
    FSnapshotHandle: THandle; 
    FProcessEntry32: TProcessEntry32; 
begin 
    SetLength(Result, 0); 
    FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
    FProcessEntry32.dwSize := SizeOf(FProcessEntry32); 
    ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32); 
    while(ContinueLoop) do 
    begin 
    if(SameText(FProcessEntry32.szExeFile, AProcessName)) then 
    begin 
     if((* is this my process? *)) then 
     begin 
     SetLength(Result, Length(Result) + 1); 
     Result[Length(Result) - 1] := FProcessEntry32.th32ProcessID; 
     end; 
    end; 
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32); 
    end; 
    CloseHandle(FSnapshotHandle); 
end; 
+0

http://stackoverflow.com/questions/559356/how-do-i-get-the-sid-session-of -an-AR bitrary-process/14845528 –

+0

@SertacAkyuz:謝謝,如果我明白了,我應該用'OpenProcess'。如果可能的話,我會避免使用該函數來避免訪問被拒絕的問題[這裏](http://stackoverflow.com/questions/40630528/is-possible-to-get-full-file-name-of-a-過程換其-I-具有-NO-權限)。有其他方法嗎?任務管理器顯示進程所屬的用戶 – ExDev

+2

我認爲您可以將OpenProcessToken與GetTokenInformation一起使用來驗證進程是否屬於運行應用程序的同一用戶。任務管理器只在提升時報告用戶名。否則,當前用戶不擁有的進程對於用戶名顯示爲空白。無論如何,你無法避免你的進程無法訪問的access_denied。 –

回答

2

我發現了一個GetUserAndDomainFromPID功能,可以輕鬆地完成任務。

正如Sertac Akyuz所建議的,該功能使用OpenProcessTokenGetTokenInformation。它還使用LookupAccountSid

uses 
    TlHelp32; 

type 
    PTOKEN_USER = ^TOKEN_USER; 
    _TOKEN_USER = record 
    User: TSidAndAttributes; 
    end; 
    TOKEN_USER = _TOKEN_USER; 

function GetUserAndDomainFromPID(ProcessId: DWORD; 
    var User, Domain: string): Boolean; 
var 
    hToken: THandle; 
    cbBuf: Cardinal; 
    ptiUser: PTOKEN_USER; 
    snu: SID_NAME_USE; 
    ProcessHandle: THandle; 
    UserSize, DomainSize: DWORD; 
    bSuccess: Boolean; 
begin 
    Result := False; 
    ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION, False, ProcessId); 
    if ProcessHandle <> 0 then 
    begin 
    // EnableProcessPrivilege(ProcessHandle, 'SeSecurityPrivilege', True); 
    if OpenProcessToken(ProcessHandle, TOKEN_QUERY, hToken) then 
    begin 
     bSuccess := GetTokenInformation(hToken, TokenUser, nil, 0, cbBuf); 
     ptiUser := nil; 
     while (not bSuccess) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) do 
     begin 
     ReallocMem(ptiUser, cbBuf); 
     bSuccess := GetTokenInformation(hToken, TokenUser, ptiUser, cbBuf, cbBuf); 
     end; 
     CloseHandle(hToken); 

     if not bSuccess then 
     begin 
     Exit; 
     end; 

     UserSize := 0; 
     DomainSize := 0; 
     LookupAccountSid(nil, ptiUser.User.Sid, nil, UserSize, nil, DomainSize, snu); 
     if (UserSize <> 0) and (DomainSize <> 0) then 
     begin 
     SetLength(User, UserSize); 
     SetLength(Domain, DomainSize); 
     if LookupAccountSid(nil, ptiUser.User.Sid, PChar(User), UserSize, 
      PChar(Domain), DomainSize, snu) then 
     begin 
      Result := True; 
      User := StrPas(PChar(User)); 
      Domain := StrPas(PChar(Domain)); 
     end; 
     end; 

     if bSuccess then 
     begin 
     FreeMem(ptiUser); 
     end; 
    end; 
    CloseHandle(ProcessHandle); 
    end; 
end; 

然後我寫了一個函數獲取當前的Windows用戶名(它使用GetUserName):

const 
    UNLEN = 256; // Maximum user name length 

function GetWindowsUsername: string; 
var 
    UserName : string; 
    UserNameLen : Dword; 
begin 
    UserNameLen := UNLEN; 
    SetLength(UserName, UserNameLen) ; 
    if GetUserName(PChar(UserName), UserNameLen) 
    then Result := Copy(UserName, 1, UserNameLen - 1) 
    else Result := ''; 
end; 

下面的函數返回的過程中所有ID組成的數組(請注意,進程按進程名稱過濾):

uses 
    TlHelp32; 

type 
    TCardinalArray = array of Cardinal; 

function GetCurrentUserPIDs(const AProcessName : string) : TCardinalArray; 
var 
    ContinueLoop: boolean; 
    FSnapshotHandle: THandle; 
    FProcessEntry32: TProcessEntry32; 
    UserName : string; 
    DomainName : string; 
    CurrentUser : string; 
begin 
    CurrentUser := GetWindowsUsername(); 

    SetLength(Result, 0); 
    FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
    FProcessEntry32.dwSize := SizeOf(FProcessEntry32); 
    ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32); 
    while(ContinueLoop) do 
    begin 
    if(SameText(FProcessEntry32.szExeFile, AProcessName)) then 
    begin 
     if(GetUserAndDomainFromPID(FProcessEntry32.th32ProcessID, UserName, DomainName)) then 
     begin 
     if(UserName = CurrentUser) then 
     begin 
      SetLength(Result, Length(Result) + 1); 
      Result[Length(Result) - 1] := FProcessEntry32.th32ProcessID; 
     end; 
     end; 
    end; 
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32); 
    end; 
    CloseHandle(FSnapshotHandle); 
end; 
相關問題