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 Prüfen mittels PID ob Prozess läuft (https://www.delphipraxis.net/168554-pruefen-mittels-pid-ob-prozess-laeuft.html)

Mohadrim 28. Mai 2012 20:14

Prüfen mittels PID ob Prozess läuft
 
Hallo,

das ganze treibt mich in den Wahnsinn. Ich hab schon einige Beiträge hier durch aber bei mir geht es nicht.

Benötigt: Ich habe eine PID als Integerwert nun möchte ich gerne prüfen, ob der Prozess dazu läuft und hätte gerne ein Ja oder Nein zurück.

Problem: Ich habe einige Sachen ausprobiert wie Beitrag http://www.delphipraxis.net/26833-pr...ng-laeuft.html wenn ich dort

[DELPHI]hProcess := GetProcessHandleFromID(GetProcessID('notepad.exe') );DELPHI]

angeb geht alles gut und er sagt das das Programm läuft. Nur wenn ich die PID direkt übergebe bekomm ich immer ein OK egal ob der Prozess läuft oder nicht obwohl es auch so wie im Beitrags Script ausgeführt wird.

Delphi-Quellcode:
...
var myHandle: THandle;
begin
myHandle := OpenProcess(SYNCHRONIZE, False, myID);
if myHandle <> 0 then
Label1.Caption := 'ok'
else
Label1.Caption := 'no';
...


Die PID stimmt definitiv und wäre auch die gleiche die im oberen Script (Link) gesagt wird.
Kann mir da jemand helfen? Wie gesagt ich will nur eine PID Abfragen und den Status bekommen mehr nicht.

Luckie 28. Mai 2012 20:28

AW: Prüfen mittels PID ob Prozess läuft
 
Und wo bekommst du die PID nachher her? Und was sagt GetLastError im Fehlerfall?

BUG 28. Mai 2012 20:37

AW: Prüfen mittels PID ob Prozess läuft
 
Du überprüfst nicht, ob ein Prozess mit der PID läuft, sondern prüfst ob diese Null ist. Wenn du sie auf einen bestimmten Wert setzt, ist sie das natürlich nie.

Außerdem sind ein Handle und eine PID auch unterschiedliche Sachen.

In dem verlinktem Beitrag ist folgender Teil interessant:
Delphi-Quellcode:
function GetProcessID(Exename: string): DWORD;
var
  hProcSnap: THandle;
  pe32: TProcessEntry32;
begin
  result := 0;
  hProcSnap := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);
  if hProcSnap <> INVALID_HANDLE_VALUE then
  begin
    pe32.dwSize := SizeOf(ProcessEntry32);
    if Process32First(hProcSnap, pe32) = true then
    begin
      while Process32Next(hProcSnap, pe32) = true do // gehe durch alle Prozesse
      begin
        if pos(Exename, pe32.szExeFile) <> 0 then
          result := pe32.th32ProcessID; // die Prozess ID wird zurückgegeben
      end;
    end;
    CloseHandle(hProcSnap);
  end;
end;
PS: @Luckie:
Wäre es so rum nicht richtiger:
Delphi-Quellcode:
 if Process32First(hProcSnap, pe32) then
    begin
      repeat // gehe durch alle Prozesse
        if pos(Exename, pe32.szExeFile) <> 0 then
          result := pe32.th32ProcessID; // die Prozess ID wird zurückgegeben
      until Process32Next(hProcSnap, pe32);
    end;

jaenicke 28. Mai 2012 21:21

AW: Prüfen mittels PID ob Prozess läuft
 
Wobei das so eigentlich kaum einen Sinn macht. Die Process ID ist Schall und Rauch, da diese nach der Beendigung eines Prozesses auch wieder vergeben wird. Ob also der Prozess noch läuft, zu dem die ID ursprünglich gehörte, oder ein neuer mit dieser ID, lässt sich aus der ID nicht feststellen.

Man kann vielleicht zusätzlich vergleichen wann der Prozess gestartet wurde um eine bestimmte Instanz zu prüfen.

Bbommel 29. Mai 2012 10:01

AW: Prüfen mittels PID ob Prozess läuft
 
Hm, nehmen wir mal an, es macht einen Sinn - ich konnte das gewünschte hier nachbauen und es läuft ohne Probleme:

Delphi-Quellcode:
procedure TForm2.Button2Click(Sender: TObject);

var myID: integer;
  hProcess: THandle;

begin
  myID:=strToInt(edit1.Text);
  hProcess := GetProcessHandleFromID(myID);
  if hProcess = 0 then
    Label1.Caption := 'Programm läuft nicht'
  else
    Label1.Caption := 'Programm läuft';
end;
Hier liegt nur ein Edit auf dem Formular, in dem man eine ID manuell eingeben kann (die man vorher über einen anderen Button sich anzeigen lassen kann). Ein Klick auf Button2 löst obige Prozedur aus. Ich habe das dann mit dem Notepad++ getestet und seine aktuelle Prozess-ID angegeben. Das Programm hat mir gesagt, dass er läuft. Dann habe ich den Notepad++ beendet und bekam die Meldung, dass er nicht mehr läuft. Alles gut also.

Will sagen: wenn du die Funktionen von Luckie so aufrufst, funktioniert das wie von dir gewünscht gewünscht. Das Problem müsste in der Tat irgendwo anders liegen. Vielleicht steht in deiner Variable zum Zeitpunkt des Aufrufs der falsche Wert, denn was vorher mit der passiert, wissen wir ja nicht. :)

Bis denn
Bommel

BUG 29. Mai 2012 11:56

AW: Prüfen mittels PID ob Prozess läuft
 
Zitat:

Zitat von Bbommel (Beitrag 1168486)
ich konnte das gewünschte hier nachbauen und es läuft ohne Probleme

Funktioniert das auch bei Prozessen ohne Fenster, also z.B. bei Kommandozeilenprogrammen?

Bbommel 29. Mai 2012 12:16

AW: Prüfen mittels PID ob Prozess läuft
 
Zitat:

Zitat von BUG (Beitrag 1168530)
Zitat:

Zitat von Bbommel (Beitrag 1168486)
ich konnte das gewünschte hier nachbauen und es läuft ohne Probleme

Funktioniert das auch bei Prozessen ohne Fenster, also z.B. bei Kommandozeilenprogrammen?

Jepp. Gerade mit einem in einer Eingabeaufforderung gestarteten Telnet-Client getestet.

Mohadrim 20. Jun 2012 08:11

AW: Prüfen mittels PID ob Prozess läuft
 
Okay hab nun noch mal alles neu eingefügt und siehe da es geht. Danke nochmal.

stahli 20. Jun 2020 21:42

AW: Prüfen mittels PID ob Prozess läuft
 
Ich prüfe auf diesem Weg, ob die bds.exe (also Delphi) läuft.

Das funktioniert auch.

Aber kann ich noch den Pfad der Exe ermitteln, um auf eine bestimmte Version zu prüfen?

Im Taskmanager kann man über Rechtsklick auch "Dateipfad öffnen" auswählen.
Kommt man an die Info heran?

himitsu 20. Jun 2020 21:47

AW: Prüfen mittels PID ob Prozess läuft
 
z.B. die Toolhelp-APIs
MSDN-Library durchsuchenProcess32First

oder via WMI

himitsu 20. Jun 2020 22:05

AW: Prüfen mittels PID ob Prozess läuft
 
Tu dir selbst einen Gefallen und schmeiß den uralten Mist mit BrowseForFolder weg, welchen man nur grauenhaft benutzen kann,
oder wenigstens schau mal nach, wie man dort das Eingabe-Edit einblendet.

Aber nimm lieber einen OpenDialog oder direkt den FileOpenDialog (ab Vista) und schalte dort in den Optionen den Verzeichnisauswahl-Modus an.

stahli 22. Jun 2020 20:40

AW: Prüfen mittels PID ob Prozess läuft
 
Danke Himi,

so ganz habe ich leider noch nichts erreicht.

Ich mache mal dort weiter... https://www.delphipraxis.net/203547-...-auslesen.html

Michael II 22. Jun 2020 21:58

AW: Prüfen mittels PID ob Prozess läuft
 
Ich nehme an, du suchst nach GetModuleFileNameEx.
Dazu gibt es viele Delphi Beispiele hier im Forum (zum Beispiel hier) und natürlich auch anderswo.

stahli 22. Jun 2020 22:05

AW: Prüfen mittels PID ob Prozess läuft
 
Vielen Dank!

Sieht gut aus. Ich schaue mir das mal in Ruhe an.

stahli 23. Jun 2020 21:41

AW: Prüfen mittels PID ob Prozess läuft
 
Vielen Dank!
Funktioniert super! :-)

HeZa 24. Jun 2020 09:07

AW: Prüfen mittels PID ob Prozess läuft
 
Hallo Stahli,
Zitat:

Zitat von stahli (Beitrag 1468141)
Vielen Dank!
Funktioniert super! :-)

der angegeben Link beinhaltet ja verschiedenste Lösungen, welche davon funktioniert denn bei dir Super?

Ciao Heza

stahli 24. Jun 2020 09:34

AW: Prüfen mittels PID ob Prozess läuft
 
Hier die Unit.
Ich habe vorher mal schnell mit dem Windows Editor etwas aufgeräumt - und hoffentlich nicht zu viel entfernt.

Delphi-Quellcode:
unit uoRegistry;

interface

uses
  { uoInstaller, meine Datenunit }
  System.Classes;

function FoundIDE(var uoItem: TuoItem {meine Datenklasse}): Boolean;
function RunningIDE(const aFileName: String): Boolean;

implementation

uses
  Winapi.Windows, System.Win.Registry, System.SysUtils,
  ShellAPI, TlHelp32, PsAPI;

const
  PROCESS_QUERY_LIMITED_INFORMATION = $1000;

function PidToFilename(const TargetPID: THandle): WideString;
type
  TQueryFullProcessImageNameW = function(hProcess: THandle; dwFlags: DWORD; lpExeName: PWideChar; nSize: PDWORD)
    : BOOL; stdcall;
var
  hProcess: THandle;
  TargetName: WideString;
  QueryFullProcessImageNameW: TQueryFullProcessImageNameW;
  nSize: cardinal;
begin
  Result := '';
  nSize := MAX_PATH;
  SetLength(TargetName, nSize);
  if Win32MajorVersion >= 6 then
  begin
    hProcess := OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, TargetPID);
    if hProcess <> 0 then
    begin
      try
        @QueryFullProcessImageNameW := GetProcAddress(GetModuleHandle('kernel32'), 'QueryFullProcessImageNameW');
        if Assigned(QueryFullProcessImageNameW) then
          if QueryFullProcessImageNameW(hProcess, 0, PWideChar(TargetName), @nSize) then
            Result := PWideChar(TargetName);
      finally
        CloseHandle(hProcess);
      end;
    end;
  end
  else
  begin
    hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, TargetPID);
    if hProcess <> 0 then
      try
        if GetModuleFileNameExW(hProcess, 0, PWideChar(TargetName), nSize) <> 0 then
          Result := PWideChar(TargetName);
      finally
        CloseHandle(hProcess);
      end;
  end;
end;

function ProcessIsRunning(const aFileName: WideString): Boolean;
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  FProcessEntry32: TProcessEntry32;
  fullPath: WideString;
  myPID: DWORD;
  OwnPID: cardinal;
begin
  OwnPID := GetCurrentProcessId;
  FSnapshotHandle := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
  Result := false;
  while Integer(ContinueLoop) <> 0 do
  begin
    try
      if UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExtractFileName(aFileName)) then
      begin
        myPID := FProcessEntry32.th32ProcessID;
        fullPath := PidToFilename(myPID);
        if SameText(fullPath, aFileName) then
        begin
          Result := True;
          Break;
        end;
      end;
      ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
    except
      ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
    end;
  end;
  CloseHandle(FSnapshotHandle);
end;

function RunningIDE(const aFileName: String): Boolean;
begin
  Result := ProcessIsRunning(aFileName);
end;

function RegKeyExists(const RegPath: string; const RootKey: HKEY): Boolean;
var
  Reg: TRegistry;
begin
  try
    Reg := TRegistry.Create;
    try
      Reg.RootKey := RootKey;
      Result := Reg.KeyExists(RegPath);
    finally
      Reg.Free;
    end;
  except
    Result := false;
  end;
end;

function RegReadStr(const RegPath, RegValue: string; var Str: string; const RootKey: HKEY): Boolean;
var
  Reg: TRegistry;
begin
  try
    Reg := TRegistry.Create;
    try
      Reg.RootKey := RootKey;
      Result := Reg.OpenKey(RegPath, true);
      if Result then
        Str := Reg.ReadString(RegValue);
    finally
      Reg.Free;
    end;
  except
    Result := false;
  end;
end;

function FoundIDE(var uoItem: TuoItem): Boolean;
var
  FileName: string;
  Found: Boolean;
begin
  Result := false;

  uoItem.IdeFileName := '';
  Found := RegKeyExists(uoItem.IdeRegPath, HKEY_CURRENT_USER);
  if (Found) then
  begin
    if (RegReadStr(uoItem.IdeRegPath, 'App', FileName, HKEY_CURRENT_USER) and (FileExists(FileName))) then
    begin
      uoItem.IdeFileName := FileName;
      Exit(true);
    end;
  end;

  Found := RegKeyExists(uoItem.IdeRegPath, HKEY_LOCAL_MACHINE);
  if (Found) then
  begin
    if (RegReadStr(uoItem.IdeRegPath, 'App', FileName, HKEY_LOCAL_MACHINE) and (FileExists(FileName))) then
    begin
      uoItem.IdeFileName := FileName;
      Exit(true);
    end;
  end;

end;

end.

HeZa 24. Jun 2020 10:49

AW: Prüfen mittels PID ob Prozess läuft
 
Zitat:

Zitat von stahli (Beitrag 1468158)
Hier die Unit.
Ich habe vorher mal schnell mit dem Windows Editor etwas aufgeräumt - und hoffentlich nicht zu viel entfernt.

Danke :thumb:


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