Geöffnete / Laufende Programme

Fragen rund um diverse Windows-Versionen, ihr Verhalten unter Xbase++ und den Umgang mit der API

Moderator: Moderatoren

Antworten
Bernd Reinhardt
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 159
Registriert: So, 16. Apr 2006 11:12
Wohnort: Öhringen

Geöffnete / Laufende Programme

Beitrag von Bernd Reinhardt »

Hallo Zusammen.
Ich muss überwachen ob anderes Programm läuft. meinprogramm.exe
Am besten wäre wenn ich mir eine Liste aller aktuell auf der Workstation ausgeführten Programme auflisten könnte.
Leider habe ich hierzu nichts mehr gefunden.
Hat mir jemand einen Tip?
Danke
Bernd
Bernd Reinhardt
fa.reinhardt@gmx.de
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Geöffnete / Laufende Programme

Beitrag von brandelh »

Da war irgendwas mit FindWindow() ...
Es gibt eine API die alle laufenden Prozesse / Fenster anzeigt, eventuell auch auf Pablos Seite
Gruß
Hubert
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: Geöffnete / Laufende Programme

Beitrag von AUGE_OHR »

such mal nach Tasklist
hier ein Anfang https://www.xbaseforum.de/viewtopic.php?f=27&t=3305
gruss by OHR
Jimmy
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: Geöffnete / Laufende Programme

Beitrag von Tom »

Oder ein simpler Batchcall:

RunShell('/C TaskList.EXE /V /FO CSV > tasklist.csv')
Herzlich,
Tom
Bernd Reinhardt
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 159
Registriert: So, 16. Apr 2006 11:12
Wohnort: Öhringen

Re: Geöffnete / Laufende Programme

Beitrag von Bernd Reinhardt »

Hallo
Danke die Spur war soweit ganz gut.

Ich Starte ein Programm und möchte wissen ob das Programm gestartet ist und läuft.
Dann so lange warten bis das Programm wieder beendet ist.
(Entspricht so ungefähr dem runshell mit lAsync = False aber runshell geht hier nicht)

Mit GetTaskList erhalte ich die Liste der Tasks allerdings wurden neu gestartete Programme nicht angezeigt.
Habe dann innerhalb meiner Warteroutine immer ein neues Fenster erzeugt oDlg2 in Appdesktop() in der Hoffnung jetzt
immer eine aktuelle Tasklist zu erhalten.
Wenn ich nun z. B. 20 Programme offen habe und starte das Programm dann zeigt es mir die offenen Programme an.
Wenn ich nun 3 Programme beende verschwinden diese auch aus der Liste. (2 Monitore, d. h. auf einem Monitor läuft das Programm auf dem anderen Monitor starte und beende ich Programme. So sehe ich sofort das Resultat. )
Wenn ich nun ein Programm wieder starte dann bleibt die Liste auf dem vorherigen Stand. Also Programme schließen wird sofort registriert, neue Programme werden nicht angezeigt.
Nur wenn ich das Programm (auf dem 1. Monitor) in Hintergrund bringe dann wieder in Vordergrund dann werden auch die neu gestarteten Programme angezeigt. Gibt es eine Möglichkeit die Tasklist zu zwingen alle Programme aufzulisten.
Version 2.00.1185

RunShell('/C TaskList.EXE /V /FO CSV > tasklist.csv') dauert zu lange bis ich ein Ergebnis habe. Bei mir 3-4 sec während GetTasklist schneller ist.
Ich rufe das oDlg2 alle sekunde auf.

Code: Alles auswählen

       oDlg2 := XbpDialog():new( AppDesktop(), , {10, 10}, {12, 60}) 
       oDlg2:clipSiblings := .T. 
       oDlg2:drawingArea:ClipChildren := .T. 
       oDlg2:create()       
       SETAPPFOCUS(oDlg2) 
       setappwindow(oDlg2)   
       aTaskList := {}   
       aTasklist := GetTaskList( oDlg2:gethWnd( ) ) 
       oDlg2:destroy()
       SetAppWindow(oDlg)  // Focus auf übergeordnetes Fenster
       SetAppFocus(oDlg)       
       altd()
       cString := time() + CRLF 
       for nI = 1 to len(aTasklist)
          cString := cString + upper(aTasklist[nI]) + CRLF
       next
       cString := cString + "Anzahl Programme: " + str(len(aTasklist), 3)
       oXbpAusgabe:setcaption(cString)   // Ausgabe der Tasklist
Gruß
Bernd
Bernd Reinhardt
fa.reinhardt@gmx.de
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2120
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 29 Mal
Danksagung erhalten: 70 Mal

Re: Geöffnete / Laufende Programme

Beitrag von Werner_Bayern »

Servus Bernd,

Code: Alles auswählen

#include "dll.ch" 
EXTERN LONG EnumWindows( EnumProc AS CALLBACK, aParam AS XPPVALUE ) IN WIN32API
EXTERN LONG IsWindowVisible( nHWND AS LONG ) IN WIN32API
EXTERN LONG GetWindowText( nHWND AS LONG, @cTxt AS STRING, nCnt AS LONG ) IN WIN32API

////////////////////////////////////////
/// /// <summary>
/// Get the windows which are currently open on the desktop. Return
/// is an array with the window titles.
/// </summary>
function ListWindowTitles()
 local oCallback
 local aRet := {}

   //
   // Create a callback object for the callback function expected by
   // the EnumWindows() Win32 API. This is a standard Xbase++ function
   // which is called implicitly by the API.
   //
   oCallback := DLLCallBack():new( "EnumWindowProc",, DLL_TYPE_UINT32, DLL_TYPE_XPPVALUE )
   EnumWindows( oCallback, aRet )
return aRet


/// <summary>
/// Xbase++ callback function to be executed by the EnumWindows()
/// Win32 API.
/// </summary>
/// <param name="nHWND">The OS-level window handle</param>
/// <param name="aWins">An array to be filled with window titles</param>
/// <returns>1 to continue enumerating OS-level windows, 0 to cancel</returns>
function EnumWindowProc( nHWND, aWins )
 local cTmp := Space( 255 )

   // Only visible windows should be listed
   if IsWindowVisible(nHWND) == 0
      return 1
   endif

   // Get the window's caption and add it to the title array
   if GetWindowText(nHWND, @cTmp, 255) == 0
      return 1
   endif
   cTmp := rtrim(cTmp)
   if asc(right(cTmp, 1)) == 0   // asc(0) entfernen!
         cTmp := left(cTmp, len(cTmp) - 1)
   endif
   AAdd( aWins, {RTrim(cTmp), nHWND} )
return 1
editiert 04.03.2020.
Zuletzt geändert von Werner_Bayern am Mi, 04. Mär 2020 23:38, insgesamt 1-mal geändert.
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: Geöffnete / Laufende Programme

Beitrag von AUGE_OHR »

hi,
Bernd Reinhardt hat geschrieben: Mo, 02. Mär 2020 19:53 Ich Starte ein Programm und möchte wissen ob das Programm gestartet ist und läuft.
Dann so lange warten bis das Programm wieder beendet ist.
(Entspricht so ungefähr dem runshell mit lAsync = False aber runshell geht hier nicht)
dann sollte man beim Start schon "Vorsorge" treffen und sich das Handle holen :!:
TRunProcess.zip
(3.95 KiB) 287-mal heruntergeladen
gruss by OHR
Jimmy
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Geöffnete / Laufende Programme

Beitrag von brandelh »

Die Frage ist doch, was dein Ziel ist ... mir fallen 2 Gründe ein ...

1. Sicherstellen, dass das Programm nach Fehler Ende wieder startet ... das macht man besser über eine Batch, die den Errorlevel abfragt.
2. Sicherstellen, dass das Programm nicht doppelt gestartet wird. Da gab es was mit Semaphoren.

in jedem Falle erscheint es mir doch sehr belastend, wenn der Rechner im Sekundentakt mitteilen soll, welche Anwendungen noch laufen.
Gruß
Hubert
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: Geöffnete / Laufende Programme

Beitrag von AUGE_OHR »

hi,

wenn man was unter Windows per API machen will benötigt man immer ein Handle.

es "nachträglich" zu "suchen" ist "umständlich" und nach "Namen" ist schlecht wenn es mehrere Instanzen gibt.
bei TrunProcess() bekommt man das Process Handle als Rückgabe Wert beim Start und das ist der Unterschied.

---

"warum" jemand "wissen" will ob eine App noch läuft ... :roll:
ich kenne solche Anfragen z.B. bezüglich Excel aber IMHO passiert es nur bei "un-saubere" Programmierung.(z.b. nicht geschlossene ActiveX Verbinduung )
gruss by OHR
Jimmy
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: Geöffnete / Laufende Programme

Beitrag von Tom »

Ich schließe mich Hubert an. Wenn man das häufiger als, sagen wir, im Minutentakt macht, belastet man die Maschine. Wenn man über das zu überwachende Programm sowieso die Kontrolle hat, lässt man es Signale dafür setzen, dass es noch aktiv ist. Das ist wirklich einfacher. Schwierig wird's nur, wenn auch das Überwachungsprogramm stirbt. :wink:
Herzlich,
Tom
Bernd Reinhardt
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 159
Registriert: So, 16. Apr 2006 11:12
Wohnort: Öhringen

Re: Geöffnete / Laufende Programme

Beitrag von Bernd Reinhardt »

Hallo
Danke für die guten Ideen.
Ich benutzte MSACCESS zum Drucken. Dort sind alle meine Berichte hinterlegt und haben eine Verbindung (Verknüpfung) zu einer DBF-Datei.
DBF Verknüpfung geht mit allen Versionen vor 2013 und nach 2016. (Für 2013 habe ich halt XML genommen geht auch).
Also die Datenbank mit Daten füllen und msaccess aufrufen über Makro, Access druckt den Bericht und beendet sich wieder.
Kunde merkt nicht das er Access benutzt und ich kann komfortabel den Bericht grafisch erstellen.
Beim Kunde reicht die Runtimeversion von Access. Kostet also auch nichts.
runshell (Datenbank, msaccess, , , )
Damit ich den nächsten Bericht erst drucke wenn der erste fertig ist warte ich bis der Prozess msaccess.exe beendet wurde.
Das ging so seit 1997 bis jetzt sehr gut.

Bei einem Kunden habe ich nun das Problem das manchmal ein Prozess von Access hängen bleibt. Damit wird runshell nicht beendet.
Wenn ich den Prozess msaccess manuell beende dann geht auch runshell weiter.
Wenn ich den Prozess von Access lasse und das Programm mit ALT C beende und neu starte geht es auch wieder normal weiter, d. h. der hängende Prozess von Access im Taskmanager stört erst mal nicht. Wenn zu viele offen sind vielleicht den Rechner mal alle paar Tage neu starten.

Deshalb war meine Überlegung runshell nicht mehr warten lassen sondern das selbst tun:

Bevor ich drucke zähle ich wie oft msaccess in Taskliste offen ist.
Dann starte ich msaccess über runshell.
Dann läuft eine Zeit von 10 sec in der ich alle 500 msec prüfen möchte wie oft msaccess offen ist.
Wenn es start + 1 ist dann druckt Access und ich verlasse die 10sec schleife.
Wenn Access mal zu schnell war und ich das nicht mitkriege dann dauert es halt 10sec bis es weiter geht.

Jetzt läuft die nächste Schleife mit 10 sec
Ich prüfe ich wieder wie oft msaccess offen ist. Wenn es wieder gleich start ist dann beende ich die Schleife.
Wenn mal wieder ein Prozess hängen bleibt dann beendet sich die Schleife nach 10sec.

Jetzt geht mein Programm normal weiter und alles geht seinen Gang. Die nächsten Berichte können gedruckt werden.

Deshalb brauche ich eine Möglichkeit schnell zu erkennen wie viele Prozesse offen sind.

Da dies beim Kunde auch öfter mal in der Nachtschicht passiert ist erst mal Eile geboten um den Fehler zu beheben.
Wie so dies nur auf einzelnen Rechnern und erst seit Anfang des Jahres passiert kann ich mir nicht erklären. (Neueste Office Version).
Aktuell habe ich das Problem nur bei einem Kunden aber dort auch gleich an mehreren Standorten.

So dies die ausführliche Beschreibung warum man so was benötigt.
Beim Kunden habe ich jetzt erst mal eine feste Wartezeit eingebaut. Runshell dann warte 15 Sekunden dann geht es immer weiter.
Diese 15 sec hätte ich gerne optimiert so das es wenn alles gut läuft es auch nicht länger dauert wie bisher mit runshell.

Grüße
Bernd
Bernd Reinhardt
fa.reinhardt@gmx.de
Benutzeravatar
HaPe
1000 working lines a day
1000 working lines a day
Beiträge: 995
Registriert: So, 15. Nov 2015 17:44
Wohnort: 71665 Vaihingen-Enz
Hat sich bedankt: 17 Mal
Danksagung erhalten: 15 Mal

Re: Geöffnete / Laufende Programme

Beitrag von HaPe »

Hallo Bernd !

Ich habe mir dafür die Funktion RunProcess erstellt, welche folgende WinAPi-Aufrufe nutzt:
- Mit CreateProcess die gewünschte EXE starten => gibt das Prozess-Handle zurück.
- In einer DO WHILE Schleife mit WaitForSingleObject prüfen ob der Prozess noch läuft.
- In der Schleife:
- DoEvents aufrufen
- Mit Sleep (auch WinApi-Funktion) warten
- Wenn der Prozess beendet ist, mit CloseHandle das zugehörige Prozess-Handle wieder schließen

Ich kann hier nicht mit Xbase++-Code dienen, da mit anderem Entwicklungs-System geschrieben.

Hier gibts was in C/C# dazu:
https://stackoverflow.com/questions/164 ... egradation

und hier im Alaska-Forum was dazu:
http://news.alaska-software.com/readmes ... 2B.generic
--
Hans-Peter
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: Geöffnete / Laufende Programme

Beitrag von AUGE_OHR »

hi,
HaPe hat geschrieben: Mi, 04. Mär 2020 19:36 Ich kann hier nicht mit Xbase++-Code dienen, da mit anderem Entwicklungs-System geschrieben.
ich fürchte das nur wenige Xbase++ User auf den Level sind.
deshalb hab ich ich auf ein "fertiges" Produkt TRunProcess.zip verwiesen.
gruss by OHR
Jimmy
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2120
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 29 Mal
Danksagung erhalten: 70 Mal

Re: Geöffnete / Laufende Programme

Beitrag von Werner_Bayern »

Servus,

in meinem Beispiel oben fehlen noch folgende Funktionen:

Code: Alles auswählen

EXTERN LONG IsWindowVisible( nHWND AS LONG ) IN WIN32API
EXTERN LONG GetWindowText( nHWND AS LONG, @cTxt AS STRING, nCnt AS LONG ) IN WIN32API


/// <summary>
/// Xbase++ callback function to be executed by the EnumWindows()
/// Win32 API.
/// </summary>
/// <param name="nHWND">The OS-level window handle</param>
/// <param name="aWins">An array to be filled with window titles</param>
/// <returns>1 to continue enumerating OS-level windows, 0 to cancel</returns>
function EnumWindowProc( nHWND, aWins )
 local cTmp := Space( 255 )

   // Only visible windows should be listed
   if IsWindowVisible(nHWND) == 0
      return 1
   endif

   // Get the window's caption and add it to the title array
   if GetWindowText(nHWND, @cTmp, 255) == 0
      return 1
   endif
   cTmp := rtrim(cTmp)
   if asc(right(cTmp, 1)) == 0   // asc(0) entfernen!
         cTmp := left(cTmp, len(cTmp) - 1)
   endif
   AAdd( aWins, {RTrim(cTmp), nHWND} )
return 1
Habs oben auch ergänzt.
es grüßt

Werner

<when the music is over, turn off the lights!>
Bernd Reinhardt
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 159
Registriert: So, 16. Apr 2006 11:12
Wohnort: Öhringen

Re: Geöffnete / Laufende Programme

Beitrag von Bernd Reinhardt »

Hallo
Ja ich habe hier meine Probleme mit der API.
Beim compilieren erhalte ich immer einen Fehler in Zeile 30)
EXTERN LONG EnumWindows( EnumProc AS CALLBACK, aParam AS XPPVALUE ) IN WIN32API
error XBT0200: Syntax Error

Muss ich in der xpj noch was ändern damit diese Zeile richtig übersetzt wird.

Gruß
Bernd
Bernd Reinhardt
fa.reinhardt@gmx.de
Benutzeravatar
BJelinek
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 218
Registriert: Sa, 02. Jun 2012 20:57
Wohnort: 73257 Köngen
Hat sich bedankt: 9 Mal
Danksagung erhalten: 3 Mal

Re: Geöffnete / Laufende Programme

Beitrag von BJelinek »

Hallo bernd

fehlt vielleicht

#include "dll.ch"

in der PRG.
Grüße
Bernd

Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2120
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 29 Mal
Danksagung erhalten: 70 Mal

Re: Geöffnete / Laufende Programme

Beitrag von Werner_Bayern »

Servus Bernd,

kopiere mal den kompletten Code von meinem 1. Post in Dein PRG, das sollte dann funktionieren.
es grüßt

Werner

<when the music is over, turn off the lights!>
Bernd Reinhardt
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 159
Registriert: So, 16. Apr 2006 11:12
Wohnort: Öhringen

Re: Geöffnete / Laufende Programme

Beitrag von Bernd Reinhardt »

Hallo Werner
Ich habe xBase++ Version 1.9 Servicelevel 1
EXTERN versteht mein Compiler nicht. Kann das Programm nicht übersetzen.

Gruß
Bernd
Bernd Reinhardt
fa.reinhardt@gmx.de
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2120
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 29 Mal
Danksagung erhalten: 70 Mal

Re: Geöffnete / Laufende Programme

Beitrag von Werner_Bayern »

Du hattest geschrieben:
Version 2.00.1185
Deshalb mein geposteter Code. Zur 1er kann ich Dir nicht helfen, ist ja steinalt...
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: Geöffnete / Laufende Programme

Beitrag von AUGE_OHR »

Bernd Reinhardt hat geschrieben: Fr, 06. Mär 2020 11:39 Ich habe xBase++ Version 1.9 Servicelevel 1
EXTERN versteht mein Compiler nicht. Kann das Programm nicht übersetzen.
dann versuche es mal mit Ot4xb
Dateianhänge
TestEnumWindows.zip
(3.56 KiB) 255-mal heruntergeladen
gruss by OHR
Jimmy
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: Geöffnete / Laufende Programme

Beitrag von AUGE_OHR »

hi,
Werner_Bayern hat geschrieben: Fr, 06. Mär 2020 13:29 Deshalb mein geposteter Code.
Zur 1er kann ich Dir nicht helfen, ist ja steinalt...
dein Code ist für "pure" Xbase++ neu
das die Xbase++ v.2.x nun auch DLLCallBack() hat ist nett ...

wie das Demo TestEnumWindows.zip gibt zeigt gibt es das bei Ot4Xb schon seit mehr als 10 Jahren.
na ja ... wenn es um Windows API geht hat Ot4Xb wohl noch einiges mehr zu bieten.
gruss by OHR
Jimmy
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2120
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 29 Mal
Danksagung erhalten: 70 Mal

Re: Geöffnete / Laufende Programme

Beitrag von Werner_Bayern »

Ja, ich freue mich auch, dass ich kein ot4xb mehr benötige. Geht jetzt alles mit Xbase++ - Bordmitteln. 8)
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: Geöffnete / Laufende Programme

Beitrag von AUGE_OHR »

Werner_Bayern hat geschrieben: Sa, 07. Mär 2020 16:54 Ja, ich freue mich auch, dass ich kein ot4xb mehr benötige. Geht jetzt alles mit Xbase++ - Bordmitteln. 8)
wenn du meinst ...
gruss by OHR
Jimmy
Antworten