我想创建一个显示此信息的任务管理器程序:
我该怎么做?
答案 0 :(得分:7)
因此,您不需要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调用此函数。
答案 1 :(得分:2)
使用PSAPI(流程状态API)。 开源JCL有一个用于PSAPI的Delphi包装器。
还有一些更好的stackoverflow Delphi PSAPI questions可以检查答案。
- 的Jeroen
答案 2 :(得分:2)
您可以使用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.
答案 3 :(得分:1)
在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属性
答案 4 :(得分:1)
ProcessInfo提供有关在Windows中运行进程的基本信息。它是开源的,包含任务管理器的演示。