2010-04-11 59 views

回答

2

使用PSAPI(进程状态API)。 开放源代码JCL有一个用于PSAPI的Delphi包装器。

还有一些更好的计算器Delphi PSAPI questions你可以检查答案。

--jeroen

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属性

7

你不需要歼(WS)CL因此,有一个简单的WinAPI的调用,它几乎所有你想要的,这是CreateToolhelp32Snapshot。为了让所有正在运行的进程的快照,你必须调用它,如下所示:

var 
    snapshot: THandle; 
begin 
    snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 

现在你有所有正在运行的进程的列表。您可以使用Process32FirstProcess32Next函数浏览此列表,列表条目是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这个功能从快照中检索。

+0

您应该删除最后一个代码片段中的动态内存分配,并简单地在堆栈中使用一个“TProcessMemoryCounters”变量。 – mghie 2010-04-11 15:53:55

+0

@mghie:如果你这么说... =) – Leo 2010-04-11 16:10:36

+0

对不起,那出错了。 S /应该/能/。 – mghie 2010-04-11 16:14:13

1

ProcessInfo提供有关在Windows中运行进程的基本信息。它是开源的,包含一个任务管理器的演示。

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. 
+0

WMI非常慢,如果NiliDelphi想要创建像TaskManager这样的刷新进程列表的东西,我经常不会推荐WMI。 – Remko 2010-04-11 20:52:54

相关问题