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 Handle- + Prozess-Fragen (https://www.delphipraxis.net/1743-handle-prozess-fragen.html)

CalganX 20. Dez 2002 16:26


Handle- + Prozess-Fragen
 
Hi,
ich habe mehrere Probleme:
  1. Wie kann ich einen Prozess, von dem ich nur den Namen (Exe-Namen) habe schließen?
  2. Wie kann herausfinden, welche Handles alle existieren?
  3. Wenn ich die herausgefunden habe, was sind das alles? Sind dass alle Formulare, oder Anwendungen? Soll heißen: Was sind Handles genau?

Die Fragen daher, da ich bisher noch nie mit Handles gearbeitet habe...

Chris

Christian Seehase 20. Dez 2002 16:39

Moin Chris,
  1. Dazu müsstest Du Dir (ein Weg) über CreateToolHelp32SnapShot und den zugehörigen Funktionen die ProzessID auslesen (Suchen, bis Du einen Prozess hast, zu dem die Exe gehört, und könntest diesen dann mit TerminateProcess beenden.
    Einfacher dürfe es sein über FindWindow ein Handle auf des Fenster der Anwendung zu beschaffen, und an dieses dann ein WM_CLOSE, oder WM_SYSCOMMAND mit Parameter SC_CLOSE, senden (SendMessage).
    Letztere Variante wäre die mit Abstand sauberste, denn bei TerminateProcess bekommt der Prozess keine Gelegenheit mehr zu Aufräumarbeiten (Resourcenfreigabe usw.)
  2. Kann ich aus dem Stand auch nicht beantworten es gibt einfach sehr viele verschiedene (Fensterhandle, Dateihandle, Objekthandle...)
  3. Mit Hilfe von EnumWindows und EnumChildWindows kannst Du Dir eine Liste aller belegten Fensterhandle organisieren. Dateihandle wüsste ich jetzt nicht genau, von sonstigen mal ganz zu schweigen.

Ganz allgemein:
Handle sind eingentlich nur Identifikationsnummern, mit denen bestimmte Objekte erkannt bzw. angesprochen werden können.
In diesen ist auch kodiert (leider weiss ich nicht wie) um was für ein Handle es sich handelt, damit die Funktionen auch ermitteln können ob das Handle für sie überhaupt gültig sein kann.
Es ist ja, z.B., unsinnig an GetWindowText ein Dateihandle zu schicken.

CalganX 20. Dez 2002 17:18

Danke für die Antwort!
  1. Also, wenn ich mir alle Fensterhandles hole, kann ich sagen, dass das alle Fenster sind, die derzeit existieren, oder?
  2. Habe das mit dem Prozess beenden jetzt mal ausprobiert. Hat aber leider nicht geklappt. Hier mal der Source:
    Delphi-Quellcode:
    var
      hHandle: THandle;
      {...}
    begin
      hHandle := FindWindow('', PChar(ListBox1.Items[ListBox1.ItemIndex]));
      SendMessage(hHandle, WM_CLOSE, SC_CLOSE, 0);
      CloseHandle(hHandle);
      getProcesses(ListBox1.Items); // nur um wieder alle Prozess wieder anzuzeigen
    end;

Chris

Chewie 20. Dez 2002 17:39

Re: Handle- + Prozess-Fragen
 
Zitat:

Zitat von Chakotay1308
  1. Wie kann ich einen Prozess, von dem ich nur den Namen (Exe-Namen) habe schließen?

Chris

Ein Prozess hat einen oder mehrere Threads. Ein Thread hat Handles, für was diese stehen, hat die Christian Seehase ja erklärt.
Nachfolgende Funktion ermittelt u. a. alle Thread-IDs einer laufenden Anwendung. Anschließend könntest du mit EnumThreadWindows und EnumChildWindow alle Handles ermitteln.
Delphi-Quellcode:
function GetThreadID(const FileName: String): TDWordList;
var
  ToolHnd, MToolHnd: THandle;
  PE32: TProcessEntry32;
  ME32: TModuleEntry32;
  TE32: TThreadEntry32;
  PIDArray, ThreadArray: TDWordList;
  a: Integer;
  PID: DWord;
begin
  PIDArray := nil;
  ThreadArray := nil;
  ToolHnd := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS or TH32CS_SNAPTHREAD, 0); //Handle auf Snapshot
  if ToolHnd = INVALID_HANDLE_VALUE then RaiseLastWin32Error;
  try
    PE32.dwSize := SizeOf(ProcessEntry32);
    if not Process32First(ToolHnd, PE32) then RaiseLastWin32Error; //erster Prozess
    repeat
      if CompareText(PE32.szExeFile, ExtractFileName(FileName)) = 0 then
      begin
        SetLength(PIDArray, Length(PIDArray) + 1);
        PIDArray[Length(PIDARRAY) - 1] := PE32.th32ProcessID;
      end;
    until not Process32Next(ToolHnd, PE32);

    { Jetzt sind alle PIDs der Prozesse, deren Dateinamen gleich dem gesuchten ist, gespeichert }
    { Jetzt wird für jeden Prozess anhand der Modulliste der vollständige Pfad ermittelt und so }
    { die endgültige, richtige ProcessID ermittelt.                                            }

    PID := 0;
    for a := 0 to Length(PIDArray) -1 do
    begin
      MToolHnd := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, PIDArray[a]); //Modulliste des gewählten Prozesses
      if MToolHnd = INVALID_HANDLE_VALUE then RaiseLastWin32Error;
      try
        ME32.dwSize := SizeOf(TModuleEntry32);
        if not Module32First(MToolhnd, ME32) then RaiseLastWin32Error;
        repeat
          if CompareText(ME32.szExePath, FileName) = 0 then
          begin
            PID := ME32.th32ProcessID;
            Break;
          end;
        until not Module32Next(MToolHnd, ME32);
      finally
        CloseHandle(MToolHnd);
      end;
      if PID <> 0 then Break;
    end;

    { Jetzt werden alle Threads des Prozesses ermittelt                                        }

    TE32.dwSize := SizeOf(ThreadEntry32);
    if not Thread32First(ToolHnd, TE32) then RaiseLastWin32Error;
    repeat
      if TE32.th32OwnerProcessID = PID then
      begin
        SetLength(ThreadArray, Length(ThreadArray) + 1);
        ThreadArray[Length(ThreadArray) - 1] := TE32.th32ThreadID;
      end;
    until not Thread32Next(ToolHnd, TE32);
  finally
    CloseHandle(ToolHnd);
  end;
  if Length(ThreadArray) > 0 then
  begin
    Result := ThreadArray;
  end else Result := nil;
end;
Du musst außerdem noch die Unit TlHelp32 einbinden und noch folgenden Typ deklarieren:
Delphi-Quellcode:
type
  TDWordList = Array of DWord;

Luckie 20. Dez 2002 17:45

Weiteres Anschauungsmaterial wäre mein Prozess-Betrachter auf meiner Seite.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:44 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 by Thomas Breitkreuz