ProcessID ermitteln [erledigt]

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

Antworten
psp
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 250
Registriert: Do, 22. Okt 2009 13:42
Kontaktdaten:

ProcessID ermitteln [erledigt]

Beitrag von psp »

Hallo,

ich habe eine kleine Frage, ob wer schon die ProcessID des gerade laufenden Programms abgefragt hat?

Ich möchte im Programm ein Watch-Dog laufen lassen, der im Notfall einen Taskkill produziert und wenn ich mit /IM appname() rangehe beendet es mir auch die neu gestartete Instanz dieser Anwendung.

Danke schon mal
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: ProcessID ermitteln

Beitrag von brandelh »

Ist das eventuell die ThreadID() -> nThreadID vom MAIN Thread ?
XbpApplication() - Klassenfunktion der XbpApplication-Klasse
ThreadObject() - Ermittelt das Thread-Objekt, das den aktuellen Thread verwaltet
Gruß
Hubert
psp
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 250
Registriert: Do, 22. Okt 2009 13:42
Kontaktdaten:

Re: ProcessID ermitteln

Beitrag von psp »

Die ProcessID ist die ID, die das Windows der Anwendung zuteilt, unter der man die Anwendung auch im Task-Manager finden kann.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: ProcessID ermitteln

Beitrag von brandelh »

Ich habe mal im PowerBasic Forum gesucht und dort wird auf die Funktion verwiesen:

GetWindowThreadProcessId( hwnd, ProcessId ) => MSDN ;-)

:arrow: http://msdn.microsoft.com/en-us/library ... 85%29.aspx
The return value is the identifier of the thread that created the window.
und da vermute ich dass dies die ThreadID vom MAIN-Thread ist, ich kann mich aber auch täuschen ;-)
Gruß
Hubert
psp
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 250
Registriert: Do, 22. Okt 2009 13:42
Kontaktdaten:

Re: ProcessID ermitteln

Beitrag von psp »

Danke für den Ansatz, leider liest die Funktion die falsche PID aus.

Gerade eben ein 10540 ausgegeben bekommen, im Taskmanager lautet sie 8244.

Ein Taskkill auf die 10540 geht mit einer Fehlermeldung raus, während der PID 8244 normal abgeschossen wird.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: ProcessID ermitteln

Beitrag von brandelh »

Jimmy hat mal was geschrieben, das die ProcessID von laufenden Anwendungen abgefragt hat: SUCHE nach "ProcessID*"

ansonsten bliebe Pablo fragen ... ;-)
Gruß
Hubert
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14641
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 87 Mal
Kontaktdaten:

Re: ProcessID ermitteln

Beitrag von Jan »

Pablo ist seit Wochen massivst überlastet. Der kommt inzwischen schon nicht einmal mehr dazu, Mails zu beantworten ...

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: ProcessID ermitteln

Beitrag von brandelh »

Man kann ja in sein Forum posten, eventuell antwortet ein anderer ;-)

Eine Xbase++ Anwendung besteht ja OHNE eigene Threads schon aus 3 Threads, davon ist einer der UIThread (=> UIThreadID())
Dort (Hilfe UIThreadID()) kann man nachlesen, dass dieser UIThread dafür sorgt, dass Windows immer "Antwort" bekommt, also müsste es genau dieser Thread sein, der eine Anwendung gegenüber von Windows per ProcessID vertritt ... allerdings sind alle ThreadID()s - auch die UIThreadID() - interne Nummer und man muss die Systemhandles ermitteln, Jimmy hat dazu was geschrieben ...
Gruß
Hubert
psp
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 250
Registriert: Do, 22. Okt 2009 13:42
Kontaktdaten:

Re: ProcessID ermitteln

Beitrag von psp »

ich habe die Suche noch mal bemüht und die Funktion gefunden

mit etwas basteln komme ich schon mal an das Ergebnis mit den Namen, aber mit den PIDs sieht es aktuell noch immer schlecht aus

Edith:

hab es raus bekommen

Ergebnis stelle ich dann hier rein
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: ProcessID ermitteln

Beitrag von brandelh »

psp hat geschrieben: hab es raus bekommen
Ergebnis stelle ich dann hier rein
schön, man weiß ja nie ob man es nochmal braucht :-)
Gruß
Hubert
psp
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 250
Registriert: Do, 22. Okt 2009 13:42
Kontaktdaten:

Re: ProcessID ermitteln

Beitrag von psp »

Code: Alles auswählen


#include "Gra.ch"
#include "Xbp.ch"
#include "Common.ch"
#include "dll.CH"

procedure main()
   cls
   ?
   ? "Test"
   ? "getProcessID()",getProcessID()
   ?
   wait

return

#define PROCESS_QUERY_INFORMATION (0x0400)
#define PROCESS_VM_READ (0x0010)

DLLFUNCTION EnumProcesses(@xPara1, xPara2, @xPara3) USING STDCALL FROM Psapi.dll
DLLFUNCTION EnumProcessModules(xPara1, @xPara2, xPara3, @xPara4) USING STDCALL FROM Psapi.dll
DLLFUNCTION GetModuleBaseNameA(xPara1, xPara2, @xPara3, xPara4) USING STDCALL FROM Psapi.dll
DLLFUNCTION GetModuleInformation(xPara1, xPara2, @xPara3, xPara4) USING STDCALL FROM Psapi.dll
DLLFUNCTION OpenProcess(xPara1, xPara2, xPara3) USING STDCALL FROM Kernel32.dll
DLLFUNCTION CloseHandle(xPara1) USING STDCALL FROM Kernel32.dll

Function getProcessID()
   Local aProcesses  := space(10240)
   Local aModules    := space(4*10)
   Local cbNeeded    := 0
   Local cbNeeded2   := 0
   LOcal cname       := space(64)
   Local lIsKill     := .F.
   Local nPid
   Local cPid :=""
   Local nProcHandle
   Local i,nMax
   LOcal hmod,nPidId
   Local xRet,aProcess:={}
   Local lStillRunning := .F.

   EnumProcesses( @aProcesses, LEN(aProcesses) , @cbNeeded )
   nMax := len(trim(aProcesses))/4
   for i:= 1 to nMax
      nPid := Bin2U(substr(aProcesses,1+((i-1)*4),4))
      if nPidId==NIL .or. (nPIdId==nPid)
         nProcHandle  := OpenProcess( PROCESS_QUERY_INFORMATION + PROCESS_VM_READ ,0, nPid )
         if nProcHandle > 0
            if  EnumProcessModules( nProcHandle, @aModules,len(aModules)/4, @cbNeeded2) != 0
               cName := space(128)
               GetModuleBaseNameA( nProcHandle,bin2u(substr(aModules,1,4)),@cName,len(cName))
               cName := strtran(cname,chr(0),"")
               CloseHandle(nProcHandle)
               cName:=upper(alltrim(cName))
               AAdd(aProcess,{cName, str(nPid)})
            endif
         endif
      endif
   next
   nScan:=aScan(aProcess, {|a| a[1]==upper(appname()) })
   if nScan>0
     cPID:=alltrim(aProcess[nScan,2])
   endif

RETURN(cPID)
psp
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 250
Registriert: Do, 22. Okt 2009 13:42
Kontaktdaten:

Re: ProcessID ermitteln [erledigt]

Beitrag von psp »

Eine Bemerkung noch.

Das Programm (=appname()) gibt nur ein Ergebnis aus, falls mehrere Instanzen davon laufen.

Ich nutze die Funktion, um die eine laufende Instanz per Taskkill zu beenden. Da das Programm selbst prüft, ob eine Instanz davon schon läuft, gehe ich dem ganzen aus dem Weg, dass ich das falsche abschieße.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: ProcessID ermitteln [erledigt]

Beitrag von brandelh »

Meinst du jetzt von DIESER Funktion wird nur die erste Instanz zurück geliefert oder ?

Wenn ja müsste man - falls das nötig wird - ein Array mit allen Instanzen (also PID) zurückgeben.
Ich meine auf der MSDN Seite waren Funktionen um Fenster nach PID zu suchen und so müsste man dann abklären (Titel, IDs ?) welches wirklich gemeint ist ...

Ich hätte ja erwartet, dass Windows das besser regelt und einfach die PID im Appcontext ablegt. :badgrin:
Gruß
Hubert
psp
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 250
Registriert: Do, 22. Okt 2009 13:42
Kontaktdaten:

Re: ProcessID ermitteln [erledigt]

Beitrag von psp »

Ja, nur die erste Instanz, was wie gesagt, bei mir kein Problem darstellt - es kann nur eine geben.

Da man hier die Liste durchgehen kann, muss man alle passenden Ergebnisse in ein Array speichern und dann ausgeben/auswerten.


In meinem Fall, wird beim Programmstart die PID abgefragt und in eine Public-Variable gelegt. Im Fehlerfall, wird in der Errorsys.prg das laufende Programm neu gestartet und dann die PID mit der Taskkill.exe abgeschossen. Das ursächliche Problem hatte ich hier auch schon mal erläutert. Es gibt Fälle, in denen das QUIT was danach folgt nicht ausgeführt wird, weil es Probleme beim Schreiben/Schließen einer oder mehrerer Datenbanken nicht funktioniert.

Diese Fehler habe ich schon mit einem Begin-Sequence-Block eingefasst und habe sie teils über Stunden laufen lassen können, ohne dass die Funktion mal das gemacht, was sie sollte. Nun ist hier auch ein Exit über die Errorsys-Funktion nach einer bestimmten Anzahl von Versuchen drin.
Antworten