1

サービスアプリケーションがサービス名だけを知って使用しているメモリの量を取得する方法はありますか?

4

3 に答える 3

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.
于 2012-06-25T21:25:19.420 に答える
2

これを行うためのデルファイ固有のコードはありませんが、これを行うためにどのWindows APIが呼び出すか(具体的にはtoolhelp dllが呼び出す)を教えてくれます。これを行うには、exeの名前を知っている必要があります(それがあなたのために働くかどうかはわかりません)。

  1. createtoolhelp32snapshotを使用してから、process32firstprocess32nextを使用してプロセスIDを見つけます。
  2. プロセスIDをOpenProcessに渡すことにより、プロセスへのハンドルを取得します
  3. プロセスハンドルをGetProcessMemoryInfoに渡します。これにより、PROCESS_MEMORY_COUNTERS構造体に、探している情報(workingSetSize構造体メンバー)が入力されます。
于 2012-06-25T21:10:40.633 に答える
0
  1. Delphiのサービス名/ハンドルからプロセスIDを見つけるにはどうすればよいですか?
  2. GetProcessMemoryInfoプロセスメトリックを見つけるため
于 2012-06-25T21:11:33.263 に答える