![]() |
Speicherauslastung eines beliebigen Prozesses anzeigen
Hallo, ich habe folgendes Problem.
Ich will auslesen, wieviel Speicher ein Prozess benötigt. Die Prozesse sammt Prozess ID und den anderen Kram anzuzeigen ist kein Problem. Ich habe auch schon eine Prozedur gefunden, mit der die Speicherauslastung des Prozesses in der ich die Prozedur ausführe anzeigen kann, aber an die anderen komm ich nicht ran...
Delphi-Quellcode:
Wie kann ich diese Prozedur so abändern, dass sie mir die Speicherauslastung von jedem beliebigen Prozess anzeigt?
uses psAPI;
procedure TForm1.Button2Click(Sender: TObject); var pmc: PPROCESS_MEMORY_COUNTERS; cb: Integer; begin cb := SizeOf(_PROCESS_MEMORY_COUNTERS); GetMem(pmc, cb); pmc^.cb := cb; if GetProcessMemoryInfo(GetCurrentProcess(), pmc, cb) then Label1.Caption := IntToStr(pmc^.WorkingSetSize) + ' Bytes' else Label1.Caption := 'Unable to retrieve memory usage structure'; FreeMem(pmc); end; |
Re: Speicherauslastung eines beliebigen Prozesses anzeigen
Wenn du GetCurrentProcess() durch OpenProcess(...) ersetzt, könntest du vielleicht zum ziel kommen ...
Sagen wir so: es sollte funktionieren ... |
Re: Speicherauslastung eines beliebigen Prozesses anzeigen
Ich hab mal ein paar Kombinationen getestet, leider führten sie nicht zum Ziel.
Die Betreffende Zeile sieht jetzt so aus:
Delphi-Quellcode:
if GetProcessMemoryInfo(OpenProcess(1, BOOL(0), PrID), pmc, cb) then
|
Re: Speicherauslastung eines beliebigen Prozesses anzeigen
Du musst dir einen anderen dwDesiredAccess -Flag suchen. Ich hab das so gelöst:
Delphi-Quellcode:
1012 is nur ne gültige PID, bei mir im moment ...
if GetProcessMemoryInfo(OpenProcess(PROCESS_ALL_ACCESS,false,1012), pmc, cb) then
Es gibt folgende Flags: MSDN PROCESS_ALL_ACCESS Specifies all possible access flags for the process object. PROCESS_CREATE_PROCESS Used internally. PROCESS_CREATE_THREAD Enables using the process handle in the CreateRemoteThread function to create a thread in the process. PROCESS_DUP_HANDLE Enables using the process handle as either the source or target process in the DuplicateHandle function to duplicate a handle. PROCESS_QUERY_INFORMATION Enables using the process handle in the GetExitCodeProcess and GetPriorityClass functions to read information from the process object. PROCESS_SET_INFORMATION Enables using the process handle in the SetPriorityClass function to set the priority class of the process. PROCESS_TERMINATE Enables using the process handle in the TerminateProcess function to terminate the process. PROCESS_VM_OPERATION Enables using the process handle in the VirtualProtectEx and WriteProcessMemory functions to modify the virtual memory of the process. PROCESS_VM_READ Enables using the process handle in the ReadProcessMemory function to read from the virtual memory of the process. PROCESS_VM_WRITE Enables using the process handle in the WriteProcessMemory function to write to the virtual memory of the process. SYNCHRONIZE Windows NT: Enables using the process handle in any of the wait functions to wait for the process to terminate. Ich hoffe, dass es jetzt funktioniert ... ciao, Philipp |
Re: Speicherauslastung eines beliebigen Prozesses anzeigen
Das funst immer noch nicht!
Delphi-Quellcode:
In der Listbox2 stehen die Prozess IDs (z.B. 0340). Eigentlich müsste es doch langsam mal laufen...
procedure TForm1.Button2Click(Sender: TObject);
var pmc: PPROCESS_MEMORY_COUNTERS; cb: Integer; PrID: Integer; // processidentifier begin PrID := StrToInt('$' + Listbox2.Items.Strings[Listbox1.Itemindex]); cb := SizeOf(_PROCESS_MEMORY_COUNTERS); GetMem(pmc, cb); pmc^.cb := cb; if GetProcessMemoryInfo(OpenProcess(PROCESS_ALL_ACCESS, false, PrID), pmc, cb) then Label1.Caption := IntToStr(pmc^.WorkingSetSize) + ' Bytes' else Label1.Caption := 'Unable to retrieve memory usage structure'; FreeMem(pmc); end; |
Re: Speicherauslastung eines beliebigen Prozesses anzeigen
Aha ... da liegt der fehler:
Delphi-Quellcode:
Die PID (ProcessID) ist nicht hexadezimal! Es ist eine einfache, ganze Zahl! Mit '$' gibst du aber an, dass es eine Hexadezimalzahl ist! Ändere das, und es sollte funktionieren.
PrID := StrToInt('$' + Listbox2.Items.Strings[Listbox1.Itemindex]);
ciao, Philipp |
Re: Speicherauslastung eines beliebigen Prozesses anzeigen
Moin Philipp,
Zitat:
|
Re: Speicherauslastung eines beliebigen Prozesses anzeigen
Doch, die PIDs sind Hexa-Dezimal! Ich hatte halt eine angegeben, die nicht Hexa-Dezimal aussieht...
|
Re: Speicherauslastung eines beliebigen Prozesses anzeigen
Moin Patrick,
leider hast Du bislang nicht angegeben, was nicht funktioniert. Am besten schreibst Du mal im else Zweig
Delphi-Quellcode:
um eine nähere Beschreibung zu bekommen, was nicht geklappt hat.
ShowMessage(SysErrorMessage(GetLastError));
Ausserdem solltest Du bei OpenProcess mal PROCESS_QUERY_INFORMATION verwenden, statt PROCESS_ALL_ACCESS. Letzteres geht bei Systemprozessen schief, da hier die Zugriffsrechte nicht ausreichen. Auch sollte man OpenProcess keinesfalls so als Parameter verwenden, da das zurückgegebene Handle auch wieder geschlossen werden muss. Das Ganze könnte z.B. so aussehen:
Delphi-Quellcode:
var
pmc : PPROCESS_MEMORY_COUNTERS; cb : Integer; PrID : Integer; // processidentifier hProc : DWORD; begin PrID := 8; cb := SizeOf(_PROCESS_MEMORY_COUNTERS); pmc := AllocMem(cb); try pmc^.cb := cb; hProc := OpenProcess(PROCESS_QUERY_INFORMATION, false, PrID); if hProc <> 0 then begin try if GetProcessMemoryInfo(hProc, pmc, cb) then begin ShowMessage(IntToStr(pmc^.WorkingSetSize) + ' Bytes'); end else begin ShowMessage(SysErrorMessage(GetLastError));; end; finally CloseHandle(hProc); end; end; finally FreeMem(pmc,SizeOf(_PROCESS_MEMORY_COUNTERS)); end; end; |
Re: Speicherauslastung eines beliebigen Prozesses anzeigen
Also sieht der Quellcode jetzt so aus:
Delphi-Quellcode:
dann funktioniert es Teilweise, mit 3 verschiedenen Fehlermeldungen, bei verschiedenen Prozessen:
procedure TForm1.Button2Click(Sender: TObject);
var pmc: PPROCESS_MEMORY_COUNTERS; cb: Integer; PrID: Integer; // processidentifier begin PrID := StrToInt('$' + Listbox2.Items.Strings[Listbox1.Itemindex]); cb := SizeOf(_PROCESS_MEMORY_COUNTERS); GetMem(pmc, cb); pmc^.cb := cb; if GetProcessMemoryInfo(OpenProcess(PROCESS_QUERY_INFORMATION, false, PrID), pmc, cb) then Label1.Caption := IntToStr(pmc^.WorkingSetSize) + ' Bytes' else Label1.Caption := 'Unable to retrieve memory usage structure'; ShowMessage(SysErrorMessage(GetLastError)); FreeMem(pmc); end; 1. Das Fenster hat keine Bildlaufleisten /mal eine interessante Meldung 2. Das Handle ist ungültig 3. irgendetwas mit nugülter Klasse / nur selten, fast willkürlich Zu bemerken ist, dass nur bei der zweiten Meldung nix gescheites angezeigt wird, mit den anderen geht es. Bei dem Quellcode von Christian funktioniert es nahezu bei jedem Prozess. Ich hab dann noch ein
Delphi-Quellcode:
eingebaut und festgestellt, dass dies (bei z.B. svchost.exe die zwei von vier Prozessen die vom SYSTEM ausgeführt werden) ein "Zugriff verweigert" ergibt. Dies war wohl beim obrigen Quellcode der selbe Fehler, halt durch eine andere Fehlermeldung ausgedrückt.
hProc := OpenProcess(PROCESS_QUERY_INFORMATION, false, PrID);
if hProc <> 0 then begin ... else ShowMessage(SysErrorMessage(GetLastError)); |
Re: Speicherauslastung eines beliebigen Prozesses anzeigen
Gehe ich richtig in der Annahme das GetProcessMemoryInfo nicht auf 9x Systemen funktioniert ?
habe die obigen Code-schnipsel mal in meine Processlist gepackt und nebenbei noch GetProcessMemoryInfo dynamisch geladen, aber ich bekomme als Ergebnis immer nur 0 Byte raus :( wenn's mit GetProcessMemoryInfo nicht funktioniert unter 9x wie können das dann andere Programme ? (WinSystem98 o.ä.) |
Re: Speicherauslastung eines beliebigen Prozesses anzeigen
Zitat:
![]() ... Und da steht, dass es nur unter NT-Systemen funzt ... oder hab ich mich verguggt? Wie es unter 9x Systemen funzt weis ich aber auch nicht ... |
Re: Speicherauslastung eines beliebigen Prozesses anzeigen
Win9x liefert diese Information, glaube ich, nicht so ohen weiteres.
|
Re: Speicherauslastung eines beliebigen Prozesses anzeigen
Liste der Anhänge anzeigen (Anzahl: 1)
dann frag ich mich, wie
![]() siehe Anhang... [edit] link *nochmal* auf neuste/letze Version geändert :) [/edit] |
Re: Speicherauslastung eines beliebigen Prozesses anzeigen
Ich sagte nicht so ohne weiteres. Ich habe nicht gesagt, dass es unmöglich sei. ;)
|
Re: Speicherauslastung eines beliebigen Prozesses anzeigen
Das es nicht unmöglich ist (grins, doppelte verneinung) seh ich ja...
nur frag ich mich wie es geht :roll: zum debuggen ist mir das teil 'n wenig zu komplex (hab mir das teil eben mit'm Disassembler angesehen) aber ich könnte ja mal versuchen den Autor zu fragen (Französisch-Kenntnisse rauskram) der hat's in VC++ 6 gelöst (lt. PeID) ;) |
Re: Speicherauslastung eines beliebigen Prozesses anzeigen
Zitat:
|
Re: Speicherauslastung eines beliebigen Prozesses anzeigen
Hi,
Habe ein VB Funktion gefunden, um die Speicherauslastung eines Prozesses anzuzeigen.
Code:
Function GetProcessMemUsage(hprocess As Long) As Long
Dim lpMem As Long Dim lPrivateBytes As Long Dim ret& Dim si As SYSTEM_INFO Dim mbi As MEMORY_BASIC_INFORMATION Dim lLenMbi& GetProcessMemUsage = -1 lLenMbi = Len(mbi) Call GetSystemInfo(si) lpMem = si.lpMinimumApplicationAddress While lpMem < si.lpMaximumApplicationAddress mbi.RegionSize = 0 ret = VirtualQueryEx(hprocess, lpMem, mbi, lLenMbi) If ret = lLenMbi Then If ((mbi.lType = MEM_private) And (mbi.State = MEM_COMMIT)) Then ' this block is In use by this process lPrivateBytes = lPrivateBytes + mbi.RegionSize End If On Error GoTo Finished lpMem = mbi.BaseAddress + mbi.RegionSize On Error GoTo 0 Else Exit Function End If Wend Finished: GetProcessMemUsage = lPrivateBytes End Function Hier ein quick & dirty Übersetzung nach Delphi:
Delphi-Quellcode:
function GetProcessMemUsage(hprocess: THandle) : Longint;
var lpMem : Cardinal; lPrivateBytes : Longint; ret:DWORD; si : TSystemInfo; mbi : TMemoryBasicInformation; lLenMbi: DWORD; x: Integer; begin GetProcessMemUsage := -1; lLenMbi := SizeOf(mbi); GetSystemInfo(si); lpMem := Cardinal(si.lpMinimumApplicationAddress); while DWORD(lpMem) < DWORD(si.lpMaximumApplicationAddress) do begin mbi.RegionSize := 0; ret := VirtualQueryEx(hprocess, Pointer(lpMem), mbi, lLenMbi); If ret = lLenMbi Then begin If ((mbi.Type_9 = MEM_private) and (mbi.State = MEM_COMMIT)) then // this block is In use by this process begin lPrivateBytes := lPrivateBytes + mbi.RegionSize end; {if} lpMem := DWORD(mbi.BaseAddress) + DWORD(mbi.RegionSize); end else begin Result := lPrivateBytes; Exit; end; end; {while} Result := lPrivateBytes; end; Problem: GetProcessMemoryInfo & GetProcessMemUsage geben nicht den gleichen Rückgabewert. Gibt wahrscheinlich einen (oder mehrere Fehler) in der Übersetzung oder die Funktion stimmt nicht ganz. |
Re: Speicherauslastung eines beliebigen Prozesses anzeigen
Zitat:
lediglich den gesamten Speicherverbrauch unter 9x brauch ich für meinen "Task-Manager" sonst muss ich halt auf diese Angabe bei 9x verzichten (wie so oft, weil die entsprechende Funktion nur NT-basiert existiert/funktioniert :twisted: ) wie auch bei meinem xNetStat :cry: |
Re: Speicherauslastung eines beliebigen Prozesses anzeigen
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:11 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz