如何使用Delphi获取其他进程的信息?

时间:2010-04-11 07:05:30

标签: delphi process

我想创建一个显示此信息的任务管理器程序:

  1. 图片名称
  2. 内存使用
  3. PID
  4. 我该怎么做?

5 个答案:

答案 0 :(得分:7)

因此,您不需要J(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调用此函数。

答案 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中运行进程的基本信息。它是开源的,包含任务管理器的演示。