如何检查进程是否属于当前用户

如何检查进程是否属于当前用户

本文介绍了如何检查进程是否属于当前用户?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试获取属于当前用户的进程的PID,但是我不知道如何检查进程所有者.

I'm trying to get PIDs of processes which belongs to the current user but I don't know how to check the process owner.

这是我的代码(缺少用户的检查条件):

This is my code (the user's checking condition is missing):

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;

推荐答案

我找到了 GetUserAndDomainFromPID 函数,该函数可轻松完成任务.

I found a GetUserAndDomainFromPID function which allows to easily accomplish the task.

如Sertac Akyuz所建议,该函数使用 OpenProcessToken GetTokenInformation .它还使用 LookupAccountSid :

As Sertac Akyuz suggested, the function uses OpenProcessToken and GetTokenInformation. It also uses 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 ):

Then I've written a function for getting the current windows username (It uses 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组成(请注意,进程是按进程名称过滤的):

The following function returns an array composed by all ids of processes who belongs to the current user (Note that processes are filtered by process name):

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;

这篇关于如何检查进程是否属于当前用户?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 05:55