【问题标题】:How to count processes starting from a full file name?如何从完整文件名开始计算进程?
【发布时间】:2016-11-03 14:35:52
【问题描述】:

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

这是我的代码:

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 &lt;&gt; 0 条件失败并执行RaiseLastOSError

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

【问题讨论】:

    标签: delphi


    【解决方案1】:

    OpenProcess 在您将 PID 设为 0 时返回 ERROR_INVALID_PARAMETER

    但是,如果您通过GetPathFromPID 函数将其传递给OpenProcess 的进程需要提升,您也可能会得到ERROR_ACCESS_DENIED

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

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

    【讨论】:

    • 你得到了我的支持,因为我忽略了很好的优化。尽管您没有解释为什么 PID 为 0。这是 OP 要求的 “但我不明白我的代码有什么问题”
    • 此代码也没有考虑短路径与长路径。短路径和长路径可以引用同一个文件。有更好的方法来比较路径是否相等。
    【解决方案2】:

    FProcessEntry32.th32ProcessID 条目可能为 0。

    例如[System Process] 的第一个进程(检查FProcessEntry32.szExeFile)的PID 为0。我很确定这是th32ProcessID == 0 的唯一条目。见"System Idle Process"

    因此,只需检查 FProcessEntry32.th32ProcessID &lt;&gt; 0,然后再将其传递给 GetPathFromPID

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-12
      • 2010-10-23
      • 2018-02-13
      • 2011-06-06
      • 1970-01-01
      相关资源
      最近更新 更多