如何从完整文件名开始计算进程?

时间:2016-11-03 14:35:53

标签: delphi

我正在尝试从可执行的完整文件名开始计算进程数。

这是我的代码:

function GetPathFromPID(const PID: cardinal): string;
var
  hProcess: THandle;
  path: array[0..MAX_PATH - 1] of char;
begin
  hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, PID);
  if hProcess <> 0 then
    try
      if GetModuleFileNameEx(hProcess, 0, path, MAX_PATH) = 0 then
        RaiseLastOSError;
      result := path;
    finally
      CloseHandle(hProcess)
    end
  else
    RaiseLastOSError;
end;

function ProcessCount(const AFullFileName: string): Integer;
var
  ContinueLoop: boolean;
  FSnapshotHandle: THandle;
  FProcessEntry32: TProcessEntry32;
begin
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
  Result := 0;
  while(ContinueLoop) do
  begin
    if ((UpperCase(GetPathFromPID(FProcessEntry32.th32ProcessID)) = UpperCase(AFullFileName)))
    then Result := Result + 1;
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
  end;
  CloseHandle(FSnapshotHandle);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Self.Caption := IntToStr(ProcessCount(Application.ExeName));
end;

GetPathFromPID函数取自here(Andreas Rejbrand的回答)。

运行应用程序,我得到了EOSError异常('系统错误。代码:87。')。正如documentation所说:

  

ERROR_INVALID_PARAMETER

     

87(0x57)

     

参数不正确。

GetPathFromPID函数引发异常,因为hProcess <> 0条件失败并且RaiseLastOSError已执行。

调试我注意到0被传递给GetPathFromPID函数作为PID参数但是我不明白我的代码中有什么问题。

2 个答案:

答案 0 :(得分:3)

当你给它一个零的PID时,

OpenProcess会返回ERROR_INVALID_PARAMETER

但如果您通过ERROR_ACCESS_DENIED功能将其传递给OpenProcess的流程需要提升,那么您也可以获得GetPathFromPID

使用此设置确保您的传递过程仅具有相同的名称。

  while (ContinueLoop) do
  begin
    if SameText(ExtractFileName(AFullFileName), FProcessEntry32.szExeFile) then
    if ((UpperCase(GetPathFromPID(FProcessEntry32.th32ProcessID)) = UpperCase(AFullFileName)))
     ....
  end;

答案 1 :(得分:3)

FProcessEntry32.th32ProcessID条目可能为0.

例如,对于[System Process](检查FProcessEntry32.szExeFile)的第一个进程,PID为0.我非常确定这是th32ProcessID == 0的唯一条目。请参阅"System Idle Process"

因此,在将FProcessEntry32.th32ProcessID <> 0传递给GetPathFromPID之前,请先检查{{1}}。