2010-04-11 41 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

相關問題