德尔福(Delphi):如何获取具有起始路径的正在运行的应用程序列表?

时间:2019-12-22 14:08:18

标签: windows delphi winapi

使用Delphi(Windows应用程序),我想获取当前正在运行的其他应用程序的列表。在How to check if a process is running using Delphi?处,我找到了有关获取正在运行的应用程序的文件名/名称的出色教程,但是它仅提供名称为进程名称(例如NOTEPAD.EXE)。我自然地将

用于
  

UpperCase(ExtractFileName(FProcessEntry32.szExeFile))

  

UpperCase(ExtractFilePath(FProcessEntry32.szExeFile))

还有

  

UpperCase(FProcessEntry32.szExeFile)

但是显然FProcessEntry32.szExeFile没有文件/进程的路径

是否有一种获取带有路径列表的简单方法?这是带有JclSysInfo库的How to get the list of running processes including full file path?解决方案,但是我不能用它代替项目中的工作。

我查看了我在Google所能提供的功能,并且发现通常只涉及正在运行的应用程序或处于活动状态的应用程序,但是我无法仅找到所有正在运行的应用程序的列表。也许我缺少明显的东西?

我不需要任何复杂的过程,我对流程权限不感兴趣,或者如果无法访问流程路径,那么我就没有了,也不会打扰。

有任何简单的提示吗?

好吧,由于@TLama提供了有益的评论,我将上面的主题结合在一起,以获取名称和过程路径:

function processExists(exeFileName: string): Boolean;
var
  ContinueLoopP, ContinueLoopM: BOOL;
  FSnapshotHandle1, FSnapshotHandle2: THandle;
  FProcessEntry32: TProcessEntry32;
  FMODULEENTRY32: TMODULEENTRY32;
begin
  FSnapshotHandle1 := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
  FMODULEENTRY32.dwSize := SizeOf(FMODULEENTRY32);
  ContinueLoopP := Process32First(FSnapshotHandle1, FProcessEntry32);
  ContinueLoopM := Module32First(FSnapshotHandle2, FMODULEENTRY32);
  Result := False;
  while Integer(ContinueLoopP) <> 0 do
  begin
    if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
      UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) =
      UpperCase(ExeFileName))) then
      Result := True;
    ShowMessage(FMODULEENTRY32.szExePath + FProcessEntry32.szExeFile);
    ContinueLoopP := Process32Next(FSnapshotHandle1, FProcessEntry32);
    ContinueLoopM := Module32Next(FSnapshotHandle2, FMODULEENTRY32);
  end;
  CloseHandle(FSnapshotHandle1);
  CloseHandle(FSnapshotHandle2);
end;

但是FProcessEntry32.szExeFile仍然返回空字符串。我做错了什么?预先谢谢你。

1 个答案:

答案 0 :(得分:3)

我无法写评论(低分),因此我需要写为“答案”。试试这个代码, 使用FProcessEntry32.th32ProcessID作为参数:

Function QueryFullProcessImageNameW(hProcess:THandle; dwFlags:Cardinal; lpExeName:PWideChar; Var lpdwSize:Cardinal) : Boolean; StdCall; External 'Kernel32.dll' Name 'QueryFullProcessImageNameW';

Function GetFullPath(Pid:Cardinal) : UnicodeString;
         Var   rLength:Cardinal;
               Handle:THandle;
         Begin Result:='';
               Handle:=OpenProcess(PROCESS_QUERY_INFORMATION, False, Pid);
               If Handle = INVALID_HANDLE_VALUE Then Exit;
               rLength:=256; // allocation buffer
               SetLength(Result, rLength+1); // for trailing space
               If Not QueryFullProcessImageNameW(Handle, 0, @Result[1],rLength) Then  Result:='' Else SetLength(Result, rLength);
               End;

这是我认为的一种简单方法。如果要获取已加载的DLL的全名,请使用 FMODULEENTRY32.hModule具有GetModuleFileNameW函数。