Seite 1 von 1
Watchdog für Programm - wie kommunizieren?
Verfasst: 16.06.2015 00:27
von Sven
Ich brauche eine Überwachung, ob ein Programm noch läuft. Nichts Sicherheitskritisches, a la Virenscanner oder so. Es soll eine Art Diashow laufen, und wenn diese wegen eines Fehlers (kaputtes Bild, falsches Dateiformat, was auch immer) hängenbleibt oder abstürzt, soll sie beendet und neu gestartet werden.
Ich habe mir das so gedacht:
Programm startet => prüft ob WD läuft, wenn nein, wird WD gestartet
Programm sendet regelmäßig Kennung an WD
empfängt der WD keine Kennung, prüft er, ob das Programm noch vorhanden ist
=> wenn ja, schließen und neu starten, sonst nur neu starten
wird Programm regulär beendet, schließt es vorher den WD
Das Programm und der WD laufen auf einem Rechner. Wie kann ich die am besten kommunizieren lassen?
Virtuelle COM-Ports? Scheint mir sehr aufwendig, erfordert wahrscheinlich spezielle Treiber.
Lokale Netzverbindung? Scheint mir immer noch etwas aufwendig.
Über den Speicher? Geht das mit modernen Windosen noch, daß zwei Programme den gleichen Speicher verwenden? Wie könnte der WD erfahren, an welcher Speicherstelle er die Kennung findet. Die könnte man ja immer hochzählen.
Ich suche keine fertigen Programme, nur Brainstorming, wie man das effizient realisieren könnte.
Re: Watchdog für Programm - wie kommunizieren?
Verfasst: 16.06.2015 01:57
von edel
Prg 1 öffnet ein unsichtbares Fenster, und setzt das handel des Fensters als Umgebungsvariable
Prg 1 startet Prg 2
Prg 2 holt sich die vererbte Umgebungsvariable, und sendet via SendMessage an das Fenster von Prg1 das WindowHandle.
Prg 1 Empfaengt WindowHandle und sendet per Timer eine Nachricht. kommt etwas zurueck, ist das Programm noch aktiv.
Beispiel :
Code: Alles auswählen
; Prg1
Enumeration #WM_USER
#UEBERTRAGE_DIA_SHOW_WINDOW_HANDLE
#REAGIERT_DIA_SHOW_WINDOW_NOCH
EndEnumeration
Global DIA_WINDOW = 0
Procedure StartDia()
RunProgram("prg2.exe")
EndProcedure
Procedure Callback(hWnd, Msg, wParam, lParam)
If Msg = #UEBERTRAGE_DIA_SHOW_WINDOW_HANDLE
DIA_WINDOW = lParam
EndIf
If Msg = #WM_TIMER
If DIA_WINDOW
If SendMessage_(DIA_WINDOW, #REAGIERT_DIA_SHOW_WINDOW_NOCH, 0, 0) = #True
Debug "Lebt noch"
Else
Debug "Lebt nicht -> starte prg"
StartDia()
Delay(300)
EndIf
Else
StartDia()
EndIf
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
Procedure Main()
Protected hWnd = 0
hWnd = OpenWindow(0, 0, 0, 0, 0, "myMessageWindow", #PB_Window_Invisible)
If hWnd
SetEnvironmentVariable("DIAMessageWindow", Str(hWnd))
SetWindowCallback(@Callback())
SetTimer_(hWnd, 0, 2000, #Null)
Repeat
WaitWindowEvent()
ForEver
EndIf
EndProcedure : End Main()
Code: Alles auswählen
; Prg2
Enumeration #WM_USER
#UEBERTRAGE_DIA_SHOW_WINDOW_HANDLE
#REAGIERT_DIA_SHOW_WINDOW_NOCH
EndEnumeration
Procedure Callback(hWnd, Msg, wParam, lParam)
If Msg = #REAGIERT_DIA_SHOW_WINDOW_NOCH
PrintN("message prg1")
ProcedureReturn #True
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
Procedure Main()
Protected hWnd = 0
OpenConsole()
OpenWindow(0, 0, 0, 100, 100, "DiaShow")
SetWindowCallback(@Callback())
hWnd = Val(GetEnvironmentVariable("DIAMessageWindow"))
SendMessage_(hWnd, #UEBERTRAGE_DIA_SHOW_WINDOW_HANDLE, 0, WindowID(0))
Repeat
Until #PB_Event_CloseWindow = WaitWindowEvent()
EndProcedure : End Main()
Re: Watchdog für Programm - wie kommunizieren?
Verfasst: 16.06.2015 08:49
von Imhotheb
vielleicht lässt sich das auch mit thread(s) lösen?
Re: Watchdog für Programm - wie kommunizieren?
Verfasst: 16.06.2015 10:10
von ts-soft
Imhotheb hat geschrieben:vielleicht lässt sich das auch mit thread(s) lösen?
Wenn das Programm abstürzt, ist normalerweise auch jeder Thread hinüber!
Sven hat geschrieben:Über den Speicher? Geht das mit modernen Windosen noch, daß zwei Programme den gleichen Speicher verwenden? Wie könnte der WD erfahren, an welcher Speicherstelle er die Kennung findet. Die könnte man ja immer hochzählen.
Vielleicht mit
FileMap bzw. SharedMemory
Re: Watchdog für Programm - wie kommunizieren?
Verfasst: 16.06.2015 21:18
von Sven
Hm, SendMessage habe ich auch schon überlegt, aber ich wollte so weit es geht mit PB-eigenen Funktionen arbeiten, um das Programm eventuell mal auf Linux übertragen zu können.
Re: Watchdog für Programm - wie kommunizieren?
Verfasst: 16.06.2015 21:40
von edel
Dann kommen eigentlich nur noch die Netzwerkbefehle in Frage. Wobei über ReadProgramData muesste das auch gehen.
Re: Watchdog für Programm - wie kommunizieren?
Verfasst: 16.06.2015 22:14
von freak
Wie wäre es mit einer einfachen Datei mit einem Zeitstempel drin?
Code: Alles auswählen
Global FileName$ = GetTemporaryDirectory() + "alive.txt"
Procedure ConfirmAlive()
If CreateFile(0, FileName$, #PB_File_NoBuffering)
WriteString(0, Str(Date()))
CloseFile(0)
EndIf
EndProcedure
OpenWindow(0, 100, 100, 300, 300, "Überwachtes Programm", #PB_Window_SystemMenu)
AddWindowTimer(0, 0, 1000)
Repeat
Select WaitWindowEvent()
Case #PB_Event_Timer
ConfirmAlive()
Case #PB_Event_CloseWindow
End
EndSelect
ForEver
Code: Alles auswählen
Global FileName$ = GetTemporaryDirectory() + "alive.txt"
Procedure IsAlive()
If ReadFile(0, FileName$)
LastAlive = Val(ReadString(0))
CloseFile(0)
If Date() - LastAlive < 5
ProcedureReturn #True
EndIf
EndIf
ProcedureReturn #False
EndProcedure
OpenWindow(0, 500, 100, 300, 300, "Überwacher", #PB_Window_SystemMenu)
AddWindowTimer(0, 0, 1000)
Repeat
Select WaitWindowEvent()
Case #PB_Event_Timer
If Not IsAlive()
MessageRequester("", "Beendet!")
End
EndIf
Case #PB_Event_CloseWindow
End
EndSelect
ForEver
Re: Watchdog für Programm - wie kommunizieren?
Verfasst: 16.06.2015 22:24
von Sven
Ja, die RunProgramm-Funktionen sehen gut aus.
Dann werde ich das wohl umkehren:
WD starten, dieser startet das Programm, liest mit ReadProgramData() die Daten vom Programm, kommen eine Zeitlang keine Daten, wird das Programm "gekillt" und neu gestartet.
@freak: Kann das nicht Ärger geben, wenn ein Programm in eine Datei schreiben will, die ein anderes Programm gerade zum Lesen geöffnet hat?
Re: Watchdog für Programm - wie kommunizieren?
Verfasst: 16.06.2015 22:38
von freak
Sven hat geschrieben:@freak: Kann das nicht Ärger geben, wenn ein Programm in eine Datei schreiben will, die ein anderes Programm gerade zum Lesen geöffnet hat?
Das Öffnen geht dann einfach schief. Da aber die Datei immer nur sehr kurz offen ist sollte das in der Praxis kein Problem sein. Der Testcode liest/schreibt jeweils einmal pro Sekunde. Wenn du das in noch größeren Intervallen machst wird es in der Praxis kein Problem sein. Dafür ist die Lösung sehr einfach.
Jetzt wo ich drüber nachdenke kann man das Leseproblem leicht lösen: Das Testprogram öffnet die Datei einfach gar nicht sondern checkt nur mit GetFileDate() das Änderungsdatum der Datei. Dann ist es garantiert kein Problem.
Re: Watchdog für Programm - wie kommunizieren?
Verfasst: 01.07.2015 22:45
von Sven
Ich hab das jetzt über Network gelöst. Der Watchdog öffnet einen Server, startet das Programm mit RunProgram() und übergibt den Serverport per Programmparameter. Das Programm meldet sich als Client an und sendet eine regelmäßige Kennung für den Reset des Watchdog. Bleibt die Kennung aus, beendet der Watchdog das Programm mit KillProgram(), wartet eine Weile und startet es neu.
Funktioniert wunderbar für mehrere Clients gleichzeitig.
Mit Read/WriteProgrammData und den Konsolenbefehlen bin ich nicht klargekommen, auch störte mich die ständig geöffnete Konsole.