Entwickler-Ecke
Windows API - Alle laufenden Prozesse listen / speicherbedarf anzeigen
Alice - Di 04.12.07 14:43
Titel: Alle laufenden Prozesse listen / speicherbedarf anzeigen
hi all,
ich versuche unter xp/vista mir alle laufenden prozesse un deren
akt. speicherverbrauch anzuzeigen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| procedure TForm1.Button2Click(Sender: TObject); var MyHandle: THandle; Struct: TProcessEntry32; begin Listbox1.Items.Clear; try MyHandle:=CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0); Struct.dwSize:=Sizeof(TProcessEntry32); if Process32First(MyHandle, Struct) then ListBox1.Items.Add(Struct.szExeFile); while Process32Next(MyHandle, Struct) do begin ListBox1.Items.Add(Struct.szExeFile + GetProcessMemorySize(Struct.th32ProcessID)); end; except on exception do ShowMessage('Error showing process list'); end;
end; |
und
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| function TForm1.GetProcessMemorySize(ProcessID: Integer): String; var Process: THandle; MemInfo: TProcessMemoryCounters; begin Process := OpenProcess(PROCESS_QUERY_INFORMATION, False, ProcessID); if (GetProcessMemoryInfo(Process, @MemInfo, SizeOf(MemInfo))) then Result := '-'+floatToStr(MemInfo.WorkingSetSize / 1024) else Result := '-0'; end; |
was soweit auch ganz gut funkt.,
nur bei einigen prozessen erhalte ich als
memorysize 0
wieso?
cu
alice
Delete - Di 04.12.07 15:58
Titel: Re: Alle laufenden Prozesse listen / speicherbedarf anzeigen
Alice hat folgendes geschrieben: |
nur bei einigen prozessen erhalte ich als
memorysize 0
wieso? |
Weil du keine Rechte hast die Prozesse zu öffnen? Würdest du mal den Rückgabewert von OpenProcess auswerten (GetLastError, ...), wüsstest du es auch.
Alice - Di 04.12.07 18:17
Titel: Re: Alle laufenden Prozesse listen / speicherbedarf anzeigen
Luckie hat folgendes geschrieben: |
Weil du keine Rechte hast die Prozesse zu öffnen? Würdest du mal den Rückgabewert von OpenProcess auswerten (GetLastError, ...), wüsstest du es auch. |
hi,
hmm...
bin als admin an der maschine angemeldet.
von daher sollte es eigentlich keinerlei probleme geben, denke ich mal!?
als getlasterror bekomme ich: 'Das Handle ist ungültig' zurück,
(bei denen die als speicherbed. eine 0 zurückgeben)
cu
alice
BlackDragon - Do 06.12.07 15:52
Hallo.
Du bist zwar als Admistrator angemeldet, aber Prozesse die vom System gestartet werden, stehen "über" dir. Du musst dir erst noch die entsprechenden Privilegien "aneignen".
Suchbegriffe:
- ImpersonateSelf
- OpenThreadToken
- SeDebugPrivilege
Alles entweder hier im Forum, in der Win32-Hilfe bei Delphi oder auf
MSDN [
http://msdn2.microsoft.com/en-us/library/] zu finden.
Das wird lustig sage ich dir. :P
Schau es dir mal an, wenn Fragen sind frag...
Mfg
Olli
Alice - Fr 07.12.07 19:38
BlackDragon hat folgendes geschrieben: |
- ImpersonateSelf
- OpenThreadToken
- SeDebugPrivilege
|
hi,
thx!
ich schaue mir die sache mal an...,
stimmt schon, ist schwieriger wie erstmal gedacht...
cu
alice
BlackDragon - Sa 08.12.07 01:42
Alice hat folgendes geschrieben: |
ich schaue mir die sache mal an...,
stimmt schon, ist schwieriger wie erstmal gedacht...
|
Bin da momentan selber dran, daher weiß ich was du meinst. Bin aber schon recht tief drin in der Materie.
Solltest du nicht klar kommen, einfach melden...
Ciao
Olli
BlackDragon - Di 11.12.07 10:56
Hi.
@Alice: Du hattest zwar eine PN gesendet, aber ich werde einen Lösungsansatz hier posten, da sicher noch einige dieses Problem haben werden.
Das Problem ist, wie bereits geschrieben, dass die nötigen Rechte fehlen um alle Informationen zu allen Prozessen zu erhalten.
Als erstes muss das Programm den Sicherheitsrahmen des lokalen Systems "imitieren". Das geschieht über den Aufruf von
ImpersonateSelf(SecurityImpersonation) [
http://msdn2.microsoft.com/en-us/library/aa378729.aspx].
Dann muss über die
OpenThreadToken [
http://msdn2.microsoft.com/en-us/library/aa379296.aspx]-Funktion ein Handle zum eigenem Thread (das Programm) mit der gewünschten Zugriffsart geöffnet werden. Über die
LookupPrivilegeValue [
http://msdn2.microsoft.com/en-us/library/aa379180.aspx]-Funktion wird eine eindeutige ID geholt, welche das entsprechende Sicherheitsprivileg beschreibt. Über den Parameter "lpName" wird der String "SeDebugPrivilege" übergeben, dadurch wird der gewünschte Zugriff bedingungslos gewährt. Diese ID braucht man um die Privilegien des eigenen Anwendung zu ändern.
Jetzt müssen die Privilegien der eigenen Anwendung noch eingestellt werden (
AdjustTokenPrivileges [
http://msdn2.microsoft.com/en-us/library/aa375202.aspx]-Funktion) und schon gibts bei der Informationsabfrage der Prozesse keine Probleme mehr.
ACHTUNG: Ich habs selbst noch nicht probiert, aber durch die erhaltenen Privilegien könnte man auch wichtige Prozesse "abschießen", auf welche man sonst keinen Zugriff hat. Es könnte also möglich sein wichtige Systemprozesse zu beenden oder deren Einstellungen zu verändern (Priorität, etc...). Es sollten außerdem aus Sicherheitsgründen die Privilegien, nach den gewünschten Aktionen, immer wieder zurückgesetzt werden.
Hier nach der Theorie nun auch mal etwas Quelltext:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72:
|
function TForm1.SetDebugPrivilege( bEnable: Boolean ): Boolean; var hToken: THandle; const SE_DEBUG_NAME = 'SeDebugPrivilege'; begin ImpersonateSelf(SecurityImpersonation); if OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, false, hToken) then begin SetPrivilege(hToken, SE_DEBUG_NAME, bEnable); CloseHandle(hToken); Result := true; end else begin Result := false; end; end;
procedure TForm1.SetPrivilege( hToken: THandle; sPrivilege: String; bEnable: Boolean ); var tp: TTokenPrivileges; tpPrev: TTokenPrivileges; luid: Int64; BufferLength: Cardinal; ReturnValue: Cardinal; begin BufferLength := SizeOf(TTokenPrivileges); LookupPrivilegeValue(nil,PAnsiChar(sPrivilege),luid); tp.PrivilegeCount := 1; tp.Privileges[0].Luid := luid; if bEnable then begin tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED; end else begin tp.Privileges[0].Attributes := 0; end; AdjustTokenPrivileges(hToken,false,tp,BufferLength,tpPrev,ReturnValue); end; |
Ich kann jetzt jederzeit über
Delphi-Quelltext
1:
| SetDebugPrivilege(true); |
die Privilegien setzen und über
Delphi-Quelltext
1:
| SetDebugPrivilege(false); |
wieder zurücksetzen.
Was ich auch noch nicht ausprobiert habe, ob es einen Unterschied bezüglich des Holens von Informationen macht "OpenProcess(...)" mit Zugriffslevel PROCESS_ALL_ACCESS aufzurufen. Eigentlich sollte PROCESS_QUERY_INFORMATION reichen.
Ich hoffe dass ich helfen konnte und ich nix vergessen bzw. falsch wiedergegeben habe. Bin halt selber noch nicht so tief in die WinAPI und deren Auswüchse eingetaucht.
Mfg
Olli
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2024 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!