Einzelnen Beitrag anzeigen

af99

Registriert seit: 22. Apr 2004
84 Beiträge
 
Delphi XE5 Ultimate
 
#1

CPU und Memory Nutzung eines Prozesses

  Alt 20. Mai 2015, 13:03
Delphi-Version: XE5
Hallo Zusammen,

ich bastele gerade an einem Programm mit dem ich die CPU und Hauptspeicher Nutzung eines benannten Prozessen ermitteln möchte.
Folgende Funktionen habe ich hierzu im Netz gefunden

Delphi-Quellcode:
function ShowMemoryUsage(ProcessId: DWORD): DWORD;
var
   hProcess: THandle;
   PMC: PPROCESS_MEMORY_COUNTERS;
   cb: Integer;
begin
   Result := 0;
   // cb := SizeOf(PMC); // = 4;
   cb := SizeOf(PMC^);
   GetMem(PMC, cb);
   try
     PMC^.cb := cb;
     hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, ProcessId);
     begin
       if ( hProcess = 0 ) then
         Exit;
       // if ( GetProcessMemoryInfo(hProcess, @PMC, SizeOf(PMC)) ) then
       if ( GetProcessMemoryInfo(hProcess, PMC, SizeOf(PMC^)) ) then
         //Result := (PMC^.WorkingSetSize Div 1024)
         Result := (PMC^.WorkingSetSize)
       else
       begin
         returntext := 'CRITICAL - ' + SysErrorMessage(GetLastError);
         returncode := 1;
       end;
     end;
   finally
     CloseHandle(hProcess);
     FreeMem(PMC, SizeOf(_PROCESS_MEMORY_COUNTERS));
   end;
end;


function GetProcessMemorySize(sProcessName: string; var nMemSize: Cardinal): Boolean;
var
  l_nWndHandle, l_nProcID, l_nTmpHandle: HWND;
  l_pPMC: PPROCESS_MEMORY_COUNTERS;
  l_pPMCSize: Cardinal;
begin
  l_nWndHandle := FindWindow(nil, PChar(sProcessName));
  if l_nWndHandle = 0 then
  begin
    writeln('fehler');
    Result := False;
    Exit;
  end;
  l_pPMCSize := SizeOf(PROCESS_MEMORY_COUNTERS);
  GetMem(l_pPMC, l_pPMCSize);
  l_pPMC^.cb := l_pPMCSize;
  GetWindowThreadProcessId(l_nWndHandle, @l_nProcID);
  l_nTmpHandle := OpenProcess(PROCESS_ALL_ACCESS, False, l_nProcID);
  if (GetProcessMemoryInfo(l_nTmpHandle, l_pPMC, l_pPMCSize)) then
    nMemSize := l_pPMC^.WorkingSetSize
  else
  begin
    writeln('fehler');
    nMemSize := 0;
  end;
  FreeMem(l_pPMC);
  CloseHandle(l_nTmpHandle);
  Result := True;
end;

// Get ProcessID By ProgramName (Include Path or Not Include)
function GetPIDByProgramName(const APName: string): THandle;
var
  isFound: boolean;
  AHandle, AhProcess: THandle;
  ProcessEntry32: TProcessEntry32;
  APath: array[0..MAX_PATH] of char;
begin
  try
    Result := 0;
    AHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    ProcessEntry32.dwSize := Sizeof(ProcessEntry32);
    isFound := Process32First(AHandle, ProcessEntry32);

    while isFound do
    begin
      AhProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
      false, ProcessEntry32.th32ProcessID);
      GetModuleFileNameEx(AhProcess, 0, @APath[0], sizeof(APath));
      if (UpperCase(StrPas(APath)) = UpperCase(APName)) or
         (UpperCase(StrPas(ProcessEntry32.szExeFile)) = UpperCase(APName)) then
      begin
        Result := ProcessEntry32.th32ProcessID;
        break;
      end;
      isFound := Process32Next(AHandle, ProcessEntry32);
      CloseHandle(AhProcess);
    end;
  finally
    CloseHandle(AHandle);
  end;
end;


function GetCpuUsage(PID:cardinal):single;
const
    cWaitTime=750;
var
    h : Cardinal;
    mCreationTime,mExitTime,mKernelTime, mUserTime:_FILETIME;
    TotalTime1,TotalTime2:int64;
begin
     {We need to get a handle of the process with PROCESS_QUERY_INFORMATION privileges.}
    h:=OpenProcess(PROCESS_QUERY_INFORMATION,false,PID);
    {We can use the GetProcessTimes() function to get the amount of time the process has spent in kernel mode and user mode.}
    GetProcessTimes(h,mCreationTime,mExitTime,mKernelTime,mUserTime);
    TotalTime1:=int64(mKernelTime.dwLowDateTime or (mKernelTime.dwHighDateTime shr 32)) + int64(mUserTime.dwLowDateTime or (mUserTime.dwHighDateTime shr 32));

    {Wait a little}
    Sleep(cWaitTime);

    GetProcessTimes(h,mCreationTime,mExitTime,mKernelTime,mUserTime);
    TotalTime2:=int64(mKernelTime.dwLowDateTime or (mKernelTime.dwHighDateTime shr 32)) + int64(mUserTime.dwLowDateTime or (mUserTime.dwHighDateTime shr 32));

    {This should work out nicely, as there were approx. 250 ms between the calls
    and the result will be a percentage between 0 and 100}

    Result:=((TotalTime2-TotalTime1)/cWaitTime)/100;
    CloseHandle(h);
end;
Für die Ermittlung des Memory Verbrauchs habe ich 2 Funktionen die ich beide versucht habe.
Ich habe nun 2 Programme geschrieben. Ein Consolenprogramm und eine VCL Formularanwendung.

In beiden Programmen rufe ich die Funktionen so auf
Delphi-Quellcode:
ww := GetProcessMemorySize(prozess_name, dmem)

oder (ich habe beide probiert)

dmem := ShowMemoryUsage(GetPIDByProgramName(prozess_name));
Wenn ich das VCL Formular Programm nun auf einem Windows Server 2008 R2 starte wird mir der Memoryverbrauch angezeicgt. Wenn ich hingegen das Consolenprogramm starte wird mir "fehler" an der Console ausgegeben
kommt hier her
Delphi-Quellcode:
  l_nWndHandle := FindWindow(nil, PChar(sProcessName));
  if l_nWndHandle = 0 then
  begin
    writeln('fehler');
    Result := False;
    Exit;
  end;
Ich habe die Console auch mal als Administrator ausgeführt. Es kommt auch "fehler" raus.
Auf einem Windows Server 2003 funktionieren beide Programme

CPU Nutzung kommt auf allen Servern und auch bei beiden Programmen raus

?!?!? Verstehe ich nicht.
Kann mir einer helfen

Viele Grüße
Andreas
  Mit Zitat antworten Zitat