Entwickler-Ecke

Windows API - Process unter WinNT anzeigen funzt net


NeoXan - Mi 24.12.03 03:37
Titel: Process unter WinNT anzeigen funzt net
Moin,

also so ungefähr hohle ich mir die laufenden Prozesse...

Delphi-Quelltext
1:
2:
3:
4:
5:
      aSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
  aProcessEntry32.dwSize := SizeOf(aProcessEntry32);
    NewItem.Caption := ExtractFileName(aProcessEntry32.szExeFile);
    NewItem.subItems.Add(IntToHex(aProcessEntry32.th32ProcessID, 4));
    NewItem.subItems.Add(aProcessEntry32.szExeFile);

dat klappt auch so weit so gut...jedenfalls mit XP...unter WinNT zeigt er nämlich gar nichts an?! Wie kann man sich die Prozesse anzeigen/beenden lassen unter NT bzw. 2000

mfg
NeoXan


Delete - Mi 24.12.03 09:43

Ich bin mir zu 99% sicher, dass sich in diesem Forum auch passender Code für das Auflisten von Prozessen befindet. Auf die Schnelle habe ich allerdings nur den FAQ [http://www.delphi-forum.de/viewtopic.php?t=13858]-Beitrag gefunden, in dem ich bei NT-Systemen einen speziellen Weg gehe, um den Dateinamen auszulesen:
Zitat:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
if(wv.dwPlatformId = VER_PLATFORM_WIN32_NT) then begin
  hp := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
    false,pid);

  if(hProcess <> INVALID_HANDLE_VALUE) then try
    ZeroMemory(@buf,sizeof(buf));
    GetModuleFileNameEx(hp,0,buf,sizeof(buf));
  finally
    CloseHandle(hp);
  end;
end;

Allerdings hat der FAQ-Beitrag jetzt nichts mit dem Auflisten aller Prozesse zu tun, er sucht anhand des Fensterhandles Pfad+Namen des Programms. Wie auch immer - ich habe auch bei Systemen wie NT und 2000 keine Probleme, den Dateinamen zu ermitteln.

Für dein Problem ist es IMHO hilfreich, die Suchfunktion [http://www.delphi-forum.de/search.php] mit Begriffen wie "Prozesse", "auflisten" usw. zu füttern und zusätzlich nach den Autoren Luckie und Motzi zu suchen. Das sollte dir einige Treffer bringen.


Delete - Mi 24.12.03 17:00

NT kennt die ToolHlpAPI nicht. Nimm statt dessen die PSAPI:

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:
uses
  PSAPI;

function GetProcessName(PID: DWORD): String;
var
  hProcess: cardinal;
  buffer : array [0..MAX_PATH-1] of Char;
begin
  result := '';
  Zeromemory(@buffer, sizeof(buffer));
  hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, FALSE,
    PID);
  if hProcess <> 0 then
  begin
    GetModulebaseName(hProcess, 0, buffer, sizeof(buffer));
    result := String(buffer);
    CloseHandle(hProcess);
  end
end;

procedure TForm1.Button1Click(Sender: TObject);
var 
  pdwResult  : PDWORD; // für den Buffer 
  pdwWork    : PDWORD; // um dem Buffer verarbeiten zu können
  dwCountIn  : DWORD;  // Grösse des Buffers in Byte 
  dwCountOut : DWORD;  // Zurückgelieferte Anzahl Byte 
  i          : integer;
begin 
  dwCountOut := 0;    // Sicherheitshalber initialisieren, muss nicht sein
  dwCountIn  := 1024; // Willkürlich gewählt, genügt für 256 Prozesse 
  pdwResult  := AllocMem(dwCountIn); 
  try 
    if not EnumProcesses(pdwResult,dwCountIn,dwCountOut) then begin 
      RaiselastOSError();
    end else begin 
      pdwWork := pdwResult; // zur Verarbeitung übergeben, damit FreeMem funktioniert 
      for i := 1 to (dwCountOut shr 2) do begin // shr 2 = / 4, da 4 Byte je DWORD
        // Prozess Id ausgeben 
        //ShowMessage('ProzessId# '+IntToStr(i)+': '+IntToStr(pdwWork^));
        ListBox1.Items.Add(GetProcessName(pdwWork^));
        // auf nächste addressieren (inc erhöht automatisch um 4, da es ein typisierter Pointer ist
        inc(pdwWork); 
      end;
    end; 
  finally 
    FreeMem(pdwResult,dwCountIn); 
  end; 
end;

Sollte unter NT / 2000 und XP gehen.