Watchdog für Programm - wie kommunizieren?
Watchdog für Programm - wie kommunizieren?
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.
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?
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 :
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()
- Imhotheb
- Beiträge: 192
- Registriert: 10.10.2014 13:14
- Computerausstattung: Intel 8086, 640 KB RAM, Hercules Video Adapter, 2 x 5 1/4" 360kb Floppy, MS-DOS 3
- Wohnort: Wolfenbüttel
Re: Watchdog für Programm - wie kommunizieren?
vielleicht lässt sich das auch mit thread(s) lösen?
weil einfach einfach einfach ist ... mach' ich es anders
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Re: Watchdog für Programm - wie kommunizieren?
Wenn das Programm abstürzt, ist normalerweise auch jeder Thread hinüber!Imhotheb hat geschrieben:vielleicht lässt sich das auch mit thread(s) lösen?
Vielleicht mit FileMap bzw. SharedMemorySven 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.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Re: Watchdog für Programm - wie kommunizieren?
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?
Dann kommen eigentlich nur noch die Netzwerkbefehle in Frage. Wobei über ReadProgramData muesste das auch gehen.
Re: Watchdog für Programm - wie kommunizieren?
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
ForEverCode: 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
ForEverRe: Watchdog für Programm - wie kommunizieren?
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?
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?
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.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?
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?
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.
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.