只知道其名称,获取服务的内存信息

时间:2012-06-25 21:02:53

标签: delphi memory-management service delphi-2010

有没有办法知道服务应用程序只使用其服务名称才能使用多少内存?

3 个答案:

答案 0 :(得分:5)

首先,您必须使用QueryServiceStatusEx函数或Win32_Service WMI类检索关联进程的Pid到服务,然后您可以使用GetProcessMemoryInfo函数来收集内存使用情况该过程的信息。

检查此示例应用

{$APPTYPE CONSOLE}

uses
  ActiveX,
  ComObj,
  Variants,
  Windows,
  psApi,
  SysUtils;

function  GetPidFromService(const ServiceName : string) : DWORD;
const
  WbemUser            ='';
  WbemPassword        ='';
  WbemComputer        ='localhost';
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService   := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
  FWbemObjectSet:= FWMIService.ExecQuery(Format('SELECT ProcessId FROM Win32_Service Where Name="%s"',[ServiceName]),'WQL',wbemFlagForwardOnly);
  oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  if oEnum.Next(1, FWbemObject, iValue) = 0 then
    Result:=FWbemObject.ProcessId;
end;

procedure MemoryInfoService(const ServiceName : string);
var
  hProcess : THandle;
  ppsmemCounters: PPROCESS_MEMORY_COUNTERS;
  cb: DWORD;
begin
  hProcess := OpenProcess(PROCESS_VM_READ or PROCESS_QUERY_INFORMATION, False, GetPidFromService(ServiceName));
  if hProcess <> 0 then
  try
   cb:=SizeOf(PROCESS_MEMORY_COUNTERS);
   GetMem(ppsmemCounters, cb);
   try
   if  GetProcessMemoryInfo( hProcess, ppsmemCounters, cb) then
   begin
      Writeln( Format('PageFaultCount: %d',[ ppsmemCounters.PageFaultCount]));
      Writeln( Format('PeakWorkingSetSize: %d',[ ppsmemCounters.PeakWorkingSetSize]));
      Writeln( Format('WorkingSetSize: %d',[ ppsmemCounters.WorkingSetSize]));
      Writeln( Format('QuotaPeakPagedPoolUsage: %d',[ ppsmemCounters.QuotaPeakPagedPoolUsage]));
      Writeln( Format('QuotaPagedPoolUsage: %d',[ ppsmemCounters.QuotaPagedPoolUsage]));
      Writeln( Format('QuotaPeakNonPagedPoolUsage: %d',[ ppsmemCounters.QuotaPeakNonPagedPoolUsage]));
      Writeln( Format('PagefileUsage: %d',[ ppsmemCounters.PagefileUsage]));
      Writeln( Format('PeakPagefileUsage: %d',[ ppsmemCounters.PeakPagefileUsage]));
   end;
   finally
     FreeMem(ppsmemCounters);
   end;
  finally
    CloseHandle(hProcess);
  end;
end;

begin
 try
    CoInitialize(nil);
    try
      MemoryInfoService('FirebirdGuardianDefaultInstance');
    finally
      CoUninitialize;
    end;
 except
    on E:EOleException do
        Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;
end.

答案 1 :(得分:2)

我没有特定于delphi的代码来执行此操作,但我可以告诉您windows api调用要执行此操作(特别是toolhelp dll调用)。要做到这一点,你需要知道exe的名称(不确定这是否适合你)。

  1. 使用 createtoolhelp32snapshot ,然后 process32first process32next 找到进程ID。
  2. 通过将流程ID传递给 OpenProcess
  3. 来获取流程句柄
  4. 将流程句柄传递给 GetProcessMemoryInfo 。这将使用您正在查找的信息填充 PROCESS_MEMORY_COUNTERS 结构(workingSetSize结构成员)。

答案 2 :(得分:0)