我想做什么:
获取所有正在运行的进程的列表:processName
(不.exe
)ProcessFullFilePath
ProcessMainWindowTitle
类似于:
process1 c:\p1.exe TheprocessTitle
..............
非常重要:
我需要工作代码不会出现任何异常(try catch
)
我的代码:
我使用TLHelp32
来获取名称列表:
var handler: THandle;
data: TProcessEntry32;
function GetName: string;
var i:byte;
begin
Result := '';
i := 0;
while data.szExeFile[i] <> '' do
begin
Result := Result + data.szExeFile[i];
Inc(i);
end;
end;
begin
Application.ShowMainForm := False;
handler := CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
if Process32First(handler, data) then
begin
ShowMessage(GetName());
while Process32Next(handler, data) do
ShowMessage(GetName());
end;
这不够,
我需要:名称路径标题
答案 0 :(得分:10)
这个功能不好:
function GetName: string;
var i:byte;
begin
Result := '';
i := 0;
while data.szExeFile[i] <> '' do
begin
Result := Result + data.szExeFile[i];
Inc(i);
end;
end;
问题是data.szExeFile[i] <> ''
始终评估True
。这是因为data.szExeFile[i]
是char
类型的单个字符,而''
是空字符串,它永远不会等于单个字符。
事实上,您可以像这样实施GetName
:
function GetName: string;
begin
Result := data.szExeFile;
end;
在按照文档中的说明调用data
之前,您还需要初始化Process32First
。你需要写:
data.dwSize := SizeOf(data);
在致电Process32First
之前。
以下是您的程序的调试版本:
{$APPTYPE CONSOLE}
uses
Windows, TlHelp32;
var
Snapshot: THandle;
pe: TProcessEntry32;
begin
Snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
try
pe.dwSize := SizeOf(pe);
if Process32First(Snapshot, pe) then
while Process32Next(Snapshot, pe) do
Writeln(pe.szExeFile);
finally
CloseHandle(Snapshot);
end;
Readln;
end.
请注意,这不会为您提供可执行文件的完整路径。要获得完整路径,您需要使用GetModuleFileNameEx
。这又需要一个流程句柄,您可以通过调用OpenProcess
从流程ID中获取该流程句柄。进程ID可在TProcessEntry32
记录中找到。
至于主窗口标题,这更棘手。许多进程都没有主窗口。甚至那些做什么,如何知道哪个窗口是主窗口?一个进程可能有多个顶级窗口,只有应用程序本身知道哪一个在概念上是主窗口。实际上可能没有单一的主窗口。如果有两个顶级窗口,则应用程序可能没有偏好哪一个是主窗口。
那就是说,你可以做的是通过调用EnumWindows
来枚举所有顶级窗口。然后为每个顶级窗口调用GetWindowThreadProcessId
。这允许您找出创建每个顶级窗口的应用程序的进程ID,从那里您应该能够将您决定所需的任何信息拼接在一起。所以,你问题的这一部分没有一个明确的答案。在进步之前,你需要准确地计算出你想要的东西。