Seite 1 von 1

Geöffnete / Laufende Programme

Verfasst: Mo, 02. Mär 2020 12:56
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

Re: Geöffnete / Laufende Programme

Verfasst: Mo, 02. Mär 2020 13:08
von brandelh
Da war irgendwas mit FindWindow() ...
Es gibt eine API die alle laufenden Prozesse / Fenster anzeigt, eventuell auch auf Pablos Seite

Re: Geöffnete / Laufende Programme

Verfasst: Mo, 02. Mär 2020 13:32
von AUGE_OHR
such mal nach Tasklist
hier ein Anfang https://www.xbaseforum.de/viewtopic.php?f=27&t=3305

Re: Geöffnete / Laufende Programme

Verfasst: Mo, 02. Mär 2020 13:56
von Tom
Oder ein simpler Batchcall:

RunShell('/C TaskList.EXE /V /FO CSV > tasklist.csv')

Re: Geöffnete / Laufende Programme

Verfasst: Mo, 02. Mär 2020 19:53
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

Re: Geöffnete / Laufende Programme

Verfasst: Mo, 02. Mär 2020 23:13
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.

Re: Geöffnete / Laufende Programme

Verfasst: Di, 03. Mär 2020 0:10
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) 294-mal heruntergeladen

Re: Geöffnete / Laufende Programme

Verfasst: Mi, 04. Mär 2020 7:17
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.

Re: Geöffnete / Laufende Programme

Verfasst: Mi, 04. Mär 2020 7:41
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 )

Re: Geöffnete / Laufende Programme

Verfasst: Mi, 04. Mär 2020 7:51
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:

Re: Geöffnete / Laufende Programme

Verfasst: Mi, 04. Mär 2020 17:16
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

Re: Geöffnete / Laufende Programme

Verfasst: Mi, 04. Mär 2020 19:36
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

Re: Geöffnete / Laufende Programme

Verfasst: Mi, 04. Mär 2020 22:37
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.

Re: Geöffnete / Laufende Programme

Verfasst: Mi, 04. Mär 2020 23:36
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.

Re: Geöffnete / Laufende Programme

Verfasst: Do, 05. Mär 2020 10:29
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

Re: Geöffnete / Laufende Programme

Verfasst: Do, 05. Mär 2020 10:40
von BJelinek
Hallo bernd

fehlt vielleicht

#include "dll.ch"

in der PRG.

Re: Geöffnete / Laufende Programme

Verfasst: Do, 05. Mär 2020 15:13
von Werner_Bayern
Servus Bernd,

kopiere mal den kompletten Code von meinem 1. Post in Dein PRG, das sollte dann funktionieren.

Re: Geöffnete / Laufende Programme

Verfasst: Fr, 06. Mär 2020 11:39
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

Re: Geöffnete / Laufende Programme

Verfasst: Fr, 06. Mär 2020 13:29
von Werner_Bayern
Du hattest geschrieben:
Version 2.00.1185
Deshalb mein geposteter Code. Zur 1er kann ich Dir nicht helfen, ist ja steinalt...

Re: Geöffnete / Laufende Programme

Verfasst: Fr, 06. Mär 2020 23:09
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

Re: Geöffnete / Laufende Programme

Verfasst: Sa, 07. Mär 2020 4:36
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.

Re: Geöffnete / Laufende Programme

Verfasst: Sa, 07. Mär 2020 16:54
von Werner_Bayern
Ja, ich freue mich auch, dass ich kein ot4xb mehr benötige. Geht jetzt alles mit Xbase++ - Bordmitteln. 8)

Re: Geöffnete / Laufende Programme

Verfasst: Sa, 07. Mär 2020 22:58
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 ...