Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Prozesse & Handles auslesen (https://www.delphipraxis.net/147895-prozesse-handles-auslesen.html)

Leon421 18. Feb 2010 13:27


Prozesse & Handles auslesen
 
Hi, ich bin auf meiner Suche nach Möglichkeiten, mit Delphi laufende Prozesse auszulesen, auf dieses Forum gestoßen, und habe mehrere Implementationen gefunden.
Alle funktionieren mehr oder weniger gut, die folgende funktioniert in sofern am besten, dass sie öfter als nicht nur die Nutzerprozesse "sieht", und ohne weiteres Filtern eine ziemlich "saubere" Liste liefert.

Versuche ich jedoch, an den Handle heranzukommen (entweder direkt über ProzessHandle, oder über die eingefügte Funktion GetProcessHandleFromID) passiert etwas absonderliches.
Ich erhalte für jede ID das gleiche Handle. Entferne ich eine der fettgedruckten "Closehandle()" zeilen, so erhalte ich für jeden Prozess eine einzigartigen Handle, jedoch scheinen diese Handles zerstört zu werden, da bei der nächsten Iteration alle Handles größer sind als vorher.

Ich bin zwar neu hier, wäre aber trotzdem ausgesprochen dankbar, falls mir Jemand helfen könnte.


Hier ist der Quelltext, mehrere Varianten waren diesem sehr ähnlich. Ich weiss leider nicht mehr, wer der Author dieser Implementation ist.

Code:
procedure DoStuff;

    function GetProcessHandleFromID(ID: DWORD): THandle;
    begin
      result := OpenProcess(SYNCHRONIZE, False, ID);
      [b]CloseHandle(result);[/b]
    end;

    var PrIDs : array [0..1000] of DWORD;
        PrName : array [0..255] of Char;
        Bia : DWORD;
        i, PrCount : Integer;
        ProzessHandle : HWND;
        Modulhandle : HWND;
    begin
    PList:=TStringList.Create;
    HList:=TStringList.Create;
    if EnumProcesses(@PrIDs, SizeOf(PrIDs), bia) then begin
       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));
                 PList.Add(ExtractFileName(PrName));
                 HList.Add(IntToStr(GetProcesshandleFromID(PrIDs[i])));

                [b] CloseHandle(ProzessHandle);[/b]
              end;
          end; {for i}
       end else begin
          MessageDlg('PrID-Array zu klein', mtError, [mbOk], 0)
       end;
    end else begin
       RaiseLastOSError();
    end;
   end;

Dezipaitor 18. Feb 2010 14:32

Re: Prozesse & Handles auslesen
 
Handles sind nichts weiter als Nummern, die von deinem Prozess in einer Liste geführt werden. Durch diese Nummer kann Windows dann speziell für deinen Prozess herausfinden, welche Ressource (z.B. Prozess) gemeint ist.
Das bedeutet, dass ein Handle auch nicht übertragbar ist auf einen anderen Prozess, da dieser eine andere Handletabelle führt. So können zwei gleiche Handles aus unterschiedlichen Prozessen auf völlig andere Resourcen (z.b. Prozess und Datei) verweisen.

Wenn du mit CloseHandle diese Nummer aus der Handleliste entfernst, dann ist sie wertlos und kann nicht weiter verwendet werden.

Jedesmal wenn du eine Resource, wie einen Verweis auf einen Prozess, anforderst, vergibt Windows deinem Prozess so eine Nummer/Handle. Und das jedesmal von neuem, so dass Handles nicht einzigartig für eine Ressource sind. Es können gerne mehrere Handles auf denselben Prozess zeigen, obwohl sie nicht dieselben Nummern sind.
Deshalb gibt es ProzessIDs, die für jeden Prozess nur einmal vergeben werden und an OpenProcess übergeben werden.

So ist dein beobachtetes Verhalten zu erklären.

Achja, Willkommen in der Delphipraxis :dp:

Leon421 18. Feb 2010 15:56

Re: Prozesse & Handles auslesen
 
D.h. ich muss wohl den Autor der Unit die fürs Terminieren der Prozesse zuständig ist, überzeugen, Prozess-IDs statt handles zum terminieren zu akzeptieren?

Vielen Dank für die Erklärung!

Luckie 18. Feb 2010 19:53

Re: Prozesse & Handles auslesen
 
Zitat:

Zitat von Leon421
D.h. ich muss wohl den Autor der Unit die fürs Terminieren der Prozesse zuständig ist, überzeugen, Prozess-IDs statt handles zum terminieren zu akzeptieren?

Wie so? Du musst das Handle nur benutzen bevor du es schließt:
Delphi-Quellcode:
function KillProcess(dwProcID, Wait: DWORD): Integer;
var
  hProcess         : Cardinal;
  dw               : DWORD;
begin
  // open the process and store the process-handle
  hProcess := OpenProcess(SYNCHRONIZE or PROCESS_TERMINATE, False, dwProcID);
  // kill it
  if hProcess <> 0 then
  begin
    dw := Integer(TerminateProcess(hProcess, 1));
    if dw <> 0 then
    begin
      // TerminateProcess returns immediately, so we have to verify the result via
      // WaitForSingleObject
      dw := WaitForSingleObject(hProcess, Wait);
      if dw = WAIT_FAILED then
        dw := GetLastError;
    end
    else // TerminateProcess = 0
      dw := GetLastError;
    CloseHandle(hProcess);
  end
  else // hProcess = INVALID_HANDLE_VALUE
    dw := GetLastError;
  result := dw;
end;

viakt133 19. Feb 2010 06:49

Re: Prozesse & Handles auslesen
 
Hallo,

Mit der Funktion GetProcessHandleFromID() sollte es dann auch möglich sein, mit dem Prozess, dessen Handle ich dann ja habe auch zu kommunizieren? Aber wie? Habe hier schon die Frage aufgeworfen. Deshalb interessiert mich auch dieser thread.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:21 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz