【发布时间】:2010-04-11 07:05:29
【问题描述】:
我想制作一个显示此信息的任务管理器程序:
- 图片名称
- 内存使用情况
- PID
我该怎么做?
【问题讨论】:
-
您恢复改善问题的编辑并添加无用的信息标签的原因是什么?
我想制作一个显示此信息的任务管理器程序:
我该怎么做?
【问题讨论】:
因此,您不需要 J(WS)CL,有一个简单的 WinAPI 调用几乎可以满足您的所有需求,这就是 CreateToolhelp32Snapshot。要获取所有正在运行的进程的快照,您必须按如下方式调用它:
var
snapshot: THandle;
begin
snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
现在您有了所有正在运行的进程的列表。您可以使用Process32First 和Process32Next 函数浏览此列表,列表条目为PROCESSENTRY32-结构(其中包含进程ID 和图像名称等)。
uses
Windows, TLHelp32, SysUtils;
var
snapshot: THandle;
ProcEntry: TProcessEntry32;
s: String;
begin
snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snapshot <> INVALID_HANDLE_VALUE) then begin
ProcEntry.dwSize := SizeOf(ProcessEntry32);
if (Process32First(snapshot, ProcEntry)) then begin
s := ProcEntry.szExeFile;
// s contains image name of the first process
while Process32Next(snapshot, ProcEntry) do begin
s := ProcEntry.szExeFile;
// s contains image name of the current process
end;
end;
end;
CloseHandle(snapshot);
但是,内存消耗信息似乎不包括在内,但您可以通过另一个简单的 API 调用获得此信息,GetProcessMemoryInfo
uses
psAPI;
var
pmc: TProcessMemoryCounters;
begin
pmc.cb := SizeOf(pmc) ;
if GetProcessMemoryInfo(processID, @pmc, SizeOf(pmc)) then
// Usage in Bytes: pmc.WorkingSetSize
else
// fail
您只需使用从快照中检索到的进程 ID 调用此函数。
【讨论】:
TProcessMemoryCounters变量。
使用PSAPI(进程状态API)。 开源JCL 有一个用于 PSAPI 的 Delphi 包装器。
还有一些更好的stackoverflowDelphi PSAPI questions你可以查看答案。
--杰罗恩
【讨论】:
您可以使用 WMI Win32_Process 类来获取所有正在运行的进程信息。此外,您可以检查Win32_PerfFormattedData_PerfProc_Process 类以获取与 CPU 和内存使用相关的性能计数器。
检查此示例
program WMIProcessInfo;
{$APPTYPE CONSOLE}
uses
SysUtils
,ActiveX
,ComObj
,Variants;
procedure GetWin32_Process;
var
objWMIService : OLEVariant;
colItems : OLEVariant;
colItem : OLEVariant;
oEnum : IEnumvariant;
iValue : LongWord;
User : OLEVariant;
Domain : OLEVariant;
function GetWMIObject(const objectName: String): IDispatch;
var
chEaten: Integer;
BindCtx: IBindCtx;
Moniker: IMoniker;
begin
OleCheck(CreateBindCtx(0, bindCtx));
OleCheck(MkParseDisplayName(BindCtx, StringToOleStr(objectName), chEaten, Moniker));
OleCheck(Moniker.BindToObject(BindCtx, nil, IDispatch, Result));
end;
begin
objWMIService := GetWMIObject('winmgmts:\\localhost\root\cimv2');
colItems := objWMIService.ExecQuery('SELECT * FROM Win32_Process','WQL',0);
oEnum := IUnknown(colItems._NewEnum) as IEnumVariant;
WriteLn(Format('%-20s %6s %10s %10s %10s',['Caption','PID','User','Domain','Working Set ( Kb Memory)']));
while oEnum.Next(1, colItem, iValue) = 0 do
begin
colItem.GetOwner(User,Domain);
if colItem.GetOwner( User, Domain ) =0 then //get the user and domain
WriteLn(Format('%-20s %6s %10s %10s %10s',[colItem.Caption,colItem.ProcessId,User,Domain,colItem.WorkingSetSize / 1024]))
else
WriteLn(Format('%-20s %6s %10s %10s %10s',[colItem.Caption,colItem.ProcessId,'','',colItem.WorkingSetSize / 1024]));
end;
end;
begin
try
CoInitialize(nil);
try
GetWin32_Process;
Readln;
finally
CoUninitialize;
end;
except
on E:Exception do
Begin
Writeln(E.Classname, ': ', E.Message);
Readln;
End;
end;
end.
【讨论】:
在 Jwscl 中有一个类可以为你做这件事(JwsclTerminalServer):
var
ATerminalServer: TJwTerminalServer;
i: Integer;
begin
// Create Terminal Server instance and allocate memory for it
ATerminalServer := TjwTerminalServer.Create;
// Set servername (only in case of remote server)
ATerminalServer.Server := 'TS001';
// Remember that EnumerateProcesses will automatically connect to the
// Terminal Server for you. The connect function raises an Exception
// if the connection attempt was unsuccessfull, so better use try..except
try
if ATerminalServer.EnumerateProcesses then
begin
// Now loop through the list
for i := 0 to ATerminalServer.Processes.Count - 1 do
begin
Memo1.Lines.Add(ATerminalServer.Processes[i].ProcessName);
end;
end;
except
on E: EJwsclWinCallFailedException do
begin
// Handle Exception here
end;
end;
// Free Memory
ATerminalServer.Free;
end;
虽然该单元是针对终端服务器的,但这部分可以在有和没有的情况下工作,并且作为奖励,您也可以在远程系统上使用它。
对于每个返回的过程详细信息,请查看文档了解详细信息。
对于内存使用,您可以使用 ProcessMemUsage 和 ProcessVirtualSize 属性,对于 Pid,有 ProcessId 属性
【讨论】:
ProcessInfo 提供有关在 Windows 中运行的进程的基本信息。它是开源的,并包含一个任务管理器的演示。
【讨论】: