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

这是我的代码:

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参数,但是我不明白我的代码有什么问题。

最佳答案

OpenProcess将PID设为零时会返回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;

10-08 13:20