我正在尝试从可执行的完整文件名开始计算进程数。
这是我的代码:
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参数但是我不明白我的代码中有什么问题。
答案 0 :(得分:3)
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}}。