Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Problem mit Auslastung durch je. Prozesse - GetProcessMemory (https://www.delphipraxis.net/50628-problem-mit-auslastung-durch-je-prozesse-getprocessmemory.html)

St.Pauli 28. Jul 2005 16:14


Problem mit Auslastung durch je. Prozesse - GetProcessMemory
 
Mein Problem ist folgendes: Ich habe eine Liste aller Prozesse (aaa.exe, bbb.exe, etc.). Nun will ich die jeweilige Auslastung mit GetProcessMemoryInfo() der PSAPI ermitteln. Das mach ich wie folgt:

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
VAR List1 : TStringList;
    i : integer;
    Item : TListItem;
    Test : PPROCESS_MEMORY_COUNTERS;
    temp : THandle;
begin
  List1 := TStringlist.Create;
  for i := 0 to List1.Count-1 do
    begin
      Item := ListView1.Items.Add;
      Item.Caption := List1.Strings[i];
      IF GetProcessMemoryInfo(GetWH(List1.Items[i]), Test, SizeOf(Test)) THEN //<- IMMER FALSE!
      Item.SubItems.Add(IntToStr(Test^.PeakWorkingSetSize));
    end;
Die Funktion GetWH ( -> getwindowhandle) sieht so aus:

Delphi-Quellcode:
function GetWH(AExeName: string): THandle;
var
  SnapShot: THandle;
  p: TProcessEntry32;
  ProcessHandle: THandle;
begin
  Result := 0;
  WindowHandle := 0;
  ProcessHandle := 0;
  p.dwSize := SizeOf(p);
  SnapShot := CreateToolhelp32Snapshot(TH32CS_SnapProcess, 0);
  try
    if Process32First(SnapShot, p) then
      repeat
      if AnsiLowerCase(AExeName) = AnsiLowerCase(p.szExeFile) then
        ProcessHandle := p.th32ProcessID;
      until (ProcessHandle <> 0) or not Process32Next(SnapShot, p);
    EnumWindows(@MyEnumWindowProc, ProcessHandle);
    Result := WindowHandle;
  finally
    CloseHandle(SnapShot);
  end;
end;
Leider wird mir nichts zurück-geliefert, da die IF-Anweisung immer false ergibt.

Olli 28. Jul 2005 18:12

Re: Problem mit Auslastung durch je. Prozesse - GetProcessMe
 
Also erstmal ist ein Prozesshandle nicht das gleiche wie eine Prozess-ID.

Außerdem übergibst du, wie ich das sehe ein Fensterhandle?!! (Statt Prozesshandle)

EDIT: Sorry nein, du übergibst natürlich IMMER 0 als Prozesshandle, weil die Funktion immer 0 zurückgibt, wie es für mich aussieht. Erklär mal den Sinn der Funktion und zeig den Code der Callback-Funktion für EnumWindows().

St.Pauli 28. Jul 2005 19:40

Re: Problem mit Auslastung durch je. Prozesse - GetProcessMe
 
ok, wer lesen kann ist klar im Vorteil. Gesucht ist das process-handle (danke das du mich drauf aufmerksam gemacht hast :-) )! Das bekomme ich jetzt zwar raus, weiter bringts mich trotzdem nicht...

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
VAR List1 : TStringList;
    i : integer;
    Item : TListItem;
    Test : PPROCESS_MEMORY_COUNTERS;
    ID : DWord;
    Temp : THandle;
begin
  List1 := TStringList.Create;
  GetProcessList(List1);
  for i := 0 to List1.Count-1 do
    begin
      Item := ListView1.Items.Add;
      Item.Caption := List1.Strings[i];
      GetWindowThreadProcessId(GetWH(List1.Strings[i]), ID); //GetWH bekommt das WindowHandl
      Temp := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, ID);
      IF GetProcessMemoryInfo(Temp, Test, SizeOf(Test)) THEN
      Item.SubItems.Add(IntToStr(Test.PeakWorkingSetSize));
    end;
end;

function GetWH(AExeName: string): THandle;
var
  SnapShot: THandle;
  p: TProcessEntry32;
  ProcessHandle: THandle;
begin
  Result := 0;
  WindowHandle := 0;
  ProcessHandle := 0;
  p.dwSize := SizeOf(p);
  SnapShot := CreateToolhelp32Snapshot(TH32CS_SnapProcess, 0);
  try
    if Process32First(SnapShot, p) then
      repeat
      if AnsiLowerCase(AExeName) = AnsiLowerCase(p.szExeFile) then
        ProcessHandle := p.th32ProcessID;
      until (ProcessHandle <> 0) or not Process32Next(SnapShot, p);
    EnumWindows(@MyEnumWindowProc, ProcessHandle);
    Result := WindowHandle;
  finally
    CloseHandle(SnapShot);
  end;
end;

function MyEnumWindowProc(AHandle: THandle; LParam: LongWord): boolean;
stdcall;
var
  ProcessID: THandle;
begin
  ProcessID := 0;
  GetWindowThreadProcessID(AHandle, ProcessID);
  Result := not (ProcessID = LParam);
  if not Result then
    WindowHandle := AHandle;
end;

Klappen tut es trotzdem nicht :gruebel:

Olli 28. Jul 2005 19:52

Re: Problem mit Auslastung durch je. Prozesse - GetProcessMe
 
Zitat:

Zitat von St.Pauli
Das bekomme ich jetzt zwar raus, weiter bringts mich trotzdem nicht...

Bist du da ganz sicher? Laß dir mal die Werte für's Fensterhandle, die PID und das Prozesshandle ausgeben!

Nenn mich doof, aber:
Code:
function GetWH(AExeName: string): THandle;
var
  SnapShot: THandle;
  p: TProcessEntry32;
  ProcessHandle: THandle;
begin
  Result := 0;
[color=red] WindowHandle := 0;[/color]
  ProcessHandle := 0;
  p.dwSize := SizeOf(p);
  SnapShot := CreateToolhelp32Snapshot(TH32CS_SnapProcess, 0);
  try
    if Process32First(SnapShot, p) then
      repeat
      if AnsiLowerCase(AExeName) = AnsiLowerCase(p.szExeFile) then
        ProcessHandle := p.th32ProcessID;
      until (ProcessHandle <> 0) or not Process32Next(SnapShot, p);
    EnumWindows(@MyEnumWindowProc, ProcessHandle);
[color=red]   Result := WindowHandle;[/color]
  finally
    CloseHandle(SnapShot);
  end;
end;
...diese Funktion gibt immernoch *immer* 0 zurück.

Kannst du also auch als
Delphi-Quellcode:
function GetWH(AExeName: string): THandle;
begin
  Result := 0;
end;
...schreiben. Ist exakt das gleiche, geht aber schneller.

St.Pauli 28. Jul 2005 20:22

Re: Problem mit Auslastung durch je. Prozesse - GetProcessMe
 
Sch*****, du hast recht, es klappt nicht. Hab zwar oben meinen Eintrag korrigiert, liefert aber immer 0 zurück! Hab das hier benutzt um das Handle zu bekommen - >hier.

Olli 28. Jul 2005 20:28

Re: Problem mit Auslastung durch je. Prozesse - GetProcessMe
 
Darf ich mal fragen, woher du die Liste der Prozeßnamen hast? Die mußt du doch auch irgendwie bekommen. Warum mußt du also überhaupt diesen umständlichen Weg über ein Fensterhandle gehen.

Erklär mal dein Ziel.

St.Pauli 28. Jul 2005 20:45

Re: Problem mit Auslastung durch je. Prozesse - GetProcessMe
 
OK, spiele gerade mit Prozessen rum. Mein Ziel ist es "The GetProcessMemoryInfo function retrieves information about the memory usage of the specified process", dass herauszubekommen - die MemoryUsage. Das erhoffe ich mir durch GetProcessMemoryInfo. Dass wird dann in einer ListView - Kolumne neben dem Process-Name und der ID angezeigt. Die Programme werden also erst in ne StringList (klappt) geladen, dann jedes einzelne in die ListView geladen, dann hol ich mir dadurch die Prozess-ID (klappt auch) und dann sollte halt die Auslastun kommen....

Wie, umständlichen Weg über Fensterhandle? Ich dachte das geht nicht anders. Ich benutze ja GetProcessMemoryInfo, dafür brauch ich am Anfang erst OpeProcess für Temp ( : THandle). Für OpenProcess benötige ich die ProcessID, die ich durch GetWindowThreadProcessId bekomme und dafür brauch ich dann am Ende das Window Handle!

Olli 28. Jul 2005 21:48

Re: Problem mit Auslastung durch je. Prozesse - GetProcessMe
 
Zitat:

Zitat von St.Pauli
Wie, umständlichen Weg über Fensterhandle? Ich dachte das geht nicht anders. Ich benutze ja GetProcessMemoryInfo, dafür brauch ich am Anfang erst OpeProcess für Temp ( : THandle). Für OpenProcess benötige ich die ProcessID, die ich durch GetWindowThreadProcessId bekomme und dafür brauch ich dann am Ende das Window Handle!

Naja, paß auf. Wenn du Code zum Auflisten der Prozesse hast, dann kannst du vermutlich bereits aus diesem Code die Prozess-IDs bekommen. Also muß man nicht erst über den Namen einer EXE auf ein Fensterhandle und von diesem auf die PID schließen.

Verstehste?!

x000x 28. Jul 2005 21:55

Re: Problem mit Auslastung durch je. Prozesse - GetProcessMe
 
Moin moin,
Zitat:

Zitat von MSDN
Return Values
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.

benutz doch mal im else Zweig vom GetProcessMemoryInfo folgendes:
Delphi-Quellcode:
//...
var
  ErrorMessage : array[0 .. 256] of Char;
  //...
begin
  //...
    IF GetProcessMemoryInfo(Temp, Test, SizeOf(Test)) THEN
      Item.SubItems.Add(IntToStr(Test.PeakWorkingSetSize))
    else begin
      FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nil, GetLastError, 0,
                    @ErrorMessage, Sizeof(ErrorMessage) - 1, nil);
      ShowMessage(ErrorMessage);
    end;
  //...
Evtl. kommste damit ein Sück weiter?!


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:09 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz