Prozessliste unter Windows NT
Funktion ENUMPROCESSES
EnumProcesses setzt sich aus den Worten "enumerate" und "processes" zusammen und bedeutet soviel wie: Prozess-Nummerierung oder Prozess-Auflistung.
Laut MSDN macht die Funktion folgendes
The EnumProcesses function retrieves the process identifier for each process object in the system..
Aufgebaut ist sie so:
Quelltext
1: 2: 3: 4: 5:
| BOOL EnumProcesses( DWORD* pProcessIds, DWORD cb, DWORD* pBytesReturned ); |
Es ist also eine Funktion mit einem Boolschen Rückgabewert (unter Delphi nennt sich das auch Boolean). Die Funktion gibt
NonZero bzw.
True zurück wenn alles geklappt hat. Wenn nicht erhalten wir
0 bzw.
False.
Sollte die Funktion schiefgegangen sein, können wir mithilfe der
RAISELASTOSERROR-Procedure den Fehler anzeigen lassen.
Parameter
- pProcessIds | Typ DWORD | Hierbei handelt es sich um einen Out-Parameter. Wir geben ihn sozusagen leer hinein und bekommen ihn mit den Process Identifiers gefüllt wieder zurück.
- cb | Typ DWORD | Die Grösse des Pointerarrays (Parameter 1). Braucht uns nicht weiter zu intressieren, siehe weiter unten.
- pBytesReturned | Typ DWORD | Ebenfalls ein Out Parameter. Hier drin wird gespeichert wieviel Bytes vom Parameter 1 - Array beschrieben wurden.
Unit
Die Funktion befindet sich in der Unit
PsApi. Also diese Unit unter Uses einbinden.
Anwendung
Bevor wir die Funktion aufrufen wissen wir nicht wieviele Prozesse momentan laufen, ergo wissen wir auch nicht wie gross wir das Array wählen sollen. Da wir die Grösse des Arrays erst beim Beschreiben kennen fällt auch ein dynamisches Array flach.
Laut MSDN
It is a good idea to use a large array, und zwar aus dem obengenannten Grund.
Wir rechnen hier jetzt allerdings mal damit dass es schwer sein dürfte 100 Prozesse gleichzeitig laufen zu haben. Sollte der Platz denoch nicht ausreichen können wir innerhalb der Funktion reagieren.
Der Quellcode:
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:
| function ProcessList:TStringList; var PrIDs : Array [0..100] of DWORD; bia : DWORD; PrCount : Integer; ProzessHandle : HWND; Modulhandle : HWND; i : Integer; PrName : Array [0..255] of Char; begin Result:=TStringList.Create; if EnumProcesses(@PrIDs, SizeOf(PrIDs), bia) then if bia < sizeof(PrIDs) then begin PrCount:=Bia div SizeOf(DWORD); for i:=0 to PrCount do begin ProzessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, PrIDS[i]); if ProzessHandle<>0 then begin EnumProcessModules(ProzessHandle, @ModulHandle, SizeOf(modulhandle), bia); GetModuleFilenameEx(Prozesshandle, ModulHandle, PrName, SizeOf(PrName)); Result.add(PrName); CloseHandle(ProzessHandle); end; end; end else messageDlg('PrID-Array zu klein', mtError, [mbOk], 0) else RaiseLastOSError(); end; |
Die ganze Prozedur läuft eigentlich recht einfach ab: Mit EnumProcesses lädt man sich die ProcessIDs aller laufenden Prozesse in das Array PrIDs. Dann geht man Prozess-ID für Prozess-ID durch, und erhält mit
OpenProcess das Prozesshandle. Wenn man das Prozesshandle hat ruft man
GetModuleFilenameEx auf in dessen Out-Parameter PrName dann der Exe-Name des laufenden Processes gespeichert wird.
Die Funktion Processlist gibt eine mit den Prozessen gefüllte Stringlist zurück. Dabei wird der komplette Pfad geliefert. Wer eine Darstellung wie Windows Taskmanager möchte, kann mit
EXTRACTFILENAME die Pfadangabe aus dem String löschen.
Wer die Funktion übrigens mit eingeschränkten Rechten ausführt, bekommt nur die Prozesse zu sehen die unter dem entsprechendem Konto laufen. Besonders bei Vista macht das mitunter Probleme: Wer unter Vista ein vollständige Prozessliste bekommen will, muss das Programm in dem sich die Funktion befindet, mit Administratorrechten starten. Andernfalls umfasst die Liste nicht alle Prozesse.
Aufrufen kann man die Funktion z.B. so:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure TForm1.Button1Click(Sender: TObject); var tmpList : TStringList; begin tmpList := ProcessList; try listbox1.items.assign(tmpList); finally tmpList.Free; end; end; |
Den Api-Befehl EnumProcesses gibt es nur auf NT-Maschinen, also Windows 2000 / XP / Vista. Wer Windows 9x benutzt muss auf
CREATETOOLHELP32SNAPSHOT ausweichen.