首页 > 解决方案 > Delphi:如何获取具有起始路径的正在运行的应用程序列表?

问题描述

使用 Delphi(Windows 应用程序)我想获取当前正在运行的其他应用程序的列表。这里如何检查一个进程是否正在使用 Delphi 运行?我找到了关于获取正在运行的应用程序的文件名/名称的很棒的教程,但是它只给出了进程名称(例如 NOTEPAD.EXE)。我用过自然的部分

大写(提取文件名(FProcessEntry32.szExeFile))

大写(ExtractFilePath(FProcessEntry32.szExeFile))

并且只是

大写(FProcessEntry32.szExeFile)

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

有没有一种简单的方法来获取路径列表?这是如何获取正在运行的进程列表,包括完整文件路径?使用 JclSysInfo 库的解决方案,但我不能在项目中使用它来代替工作。

我查看了我在 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 仍然返回空字符串。我做错了什么?先感谢您。

标签: windowsdelphiwinapi

解决方案


我不能写评论(低分),所以我需要写为“答案”。试试这个代码,使用 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 函数。


推荐阅读