Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Prüfen ob Programm abgestürzt ist (https://www.delphipraxis.net/177915-pruefen-ob-programm-abgestuerzt-ist.html)

iDope 5. Dez 2013 12:49

Prüfen ob Programm abgestürzt ist
 
Hallo zusammen,

Ich möchte ein Programm schreiben, welches ein Programm auf einem, im Netzwerk liegenden, Rechner auf Aktivität prüft.

Die WMI hab ich mir schonmal angeschaut. Hat jemand so etwas ähnliches schonmal gemacht oder hätte evtl Tipps wie oder wo ich diese "Rückmeldung" herbekommen könnte?

Der schöne Günther 5. Dez 2013 13:05

AW: Prüfen ob Programm abgestürzt ist
 
"Auf Aktivität prüfen" und "Prüfen, ob ein Prozess abstürzt" sind meiner Meinung nach zwei verschiedene Dinge. Was genau?

"Das Programm" das überprüft werden soll kann nicht modifiziert werden, oder?

Sherlock 5. Dez 2013 13:06

AW: Prüfen ob Programm abgestürzt ist
 
Ist das zu überprüfende Programm Dein eigenes? Wenn nein, verweise ich auf das Halteproblem. Falls ja, musst Du genau ermitteln, was für Kriterien einem Absturz entsprechen.

Sherlock

iDope 6. Dez 2013 08:45

AW: Prüfen ob Programm abgestürzt ist
 
Das zu überprüfende Programm ist nicht meines, somit kann es auch nicht modifiziert werden. Es soll überprüft werden ob, das Programm noch arbeitet oder ob es abgesürtzt ist und neu gestartet werden muss.

Vielen Dank (:

SirThornberry 6. Dez 2013 09:58

AW: Prüfen ob Programm abgestürzt ist
 
Wie definierst du abgestürzt?
1: Ist der Prozess noch aktiv aber das Programm reagiert nicht mehr?
2: Oder ist der Prozess geschlossen?
3: Hat das Programm ein Dienst oder hat es vielleicht sogar ein Hauptfenster welches man dann ansprechen könnte um zu sehen ob das Programm noch reagiert?

Luckie 6. Dez 2013 13:02

AW: Prüfen ob Programm abgestürzt ist
 
Besitzt der Prozess ein Fenster könnte man mit SendMessageTimeOut die Nachricht WM_NULL an das Fenster schicken. Oder guck mal hier: http://blogs.msdn.com/b/ntdebugging/...lications.aspx (Detecting and automatically dumping hung GUI based windows applications..) Den Debug-Kram kannst du ja weglassen.

taveuni 6. Dez 2013 14:19

AW: Prüfen ob Programm abgestürzt ist
 
Prüfen ob ein fremdes Programm abgestürzt ist - ist absolut unmöglich.
Diesbezüglich haben wir schon Mannmonate investiert und schlussendlich aufgegeben.

Wie oben schon jemand geschrieben hat geht es um die Kriterien. Ist ein Programm abgestürzt wenn:
Wenn nur das Fenster nicht mehr antwortet (Programm reagiert nicht mehr)-
kommt darauf an wie es programmiert ist. Wenn alles im Hauptthread abläuft - vergiss es.

Selbst wenn das Programm oder der Dienst eine Schnittstelle hat und einen Heartbeat sendet.
Was weiss der Überprüfer dann mehr? Nur dass der Heartbeat noch arbeitet.

iDope 6. Dez 2013 14:27

AW: Prüfen ob Programm abgestürzt ist
 
Okay, vielen Dank. Das SendmessageTimeout funktioniert zumindest mit méinem testprogramm. Ich werde es im lauzfe der nächsten Woche am eigentlichen Programm testen.

Olli73 6. Dez 2013 14:52

AW: Prüfen ob Programm abgestürzt ist
 
Schade! Ich hatte schon gehofft, dass hier ein zukünftiger Nobelpreisträger anwesend ist, der eine generelle Lösung anbieten kann. ;)

Furtbichler 6. Dez 2013 18:43

AW: Prüfen ob Programm abgestürzt ist
 
Auf dem lokalen PC kann man eine hängende Anwendung so erkennen:

Delphi-Quellcode:
function IsAppRespondingNT(wnd: HWND): Boolean;
type
  TIsHungAppWindow = function(wnd:hWnd): BOOL; stdcall;
var
  hKernel: THandle;
  IsHungAppWindow: TIsHungAppWindow;
begin
  Result := True;
  hKernel := GetModuleHandle('user32.dll');
  if (hKernel > 0) then
  begin
    @IsHungAppWindow := GetProcAddress(hKernel, 'IsHungAppWindow');
    if Assigned(IsHungAppWindow) then
    begin
      Result := not IsHungAppWindow(wnd);
    end;
  end;
end;

function IsAppResponding(Wnd: HWND): Boolean;
begin
 if not IsWindow(Wnd) then
 begin
   ShowMessage('Incorrect window handle');
 Exit;
 end;
 if Win32Platform = VER_PLATFORM_WIN32_NT then
   Result := IsAppRespondingNT(wnd)
 else
   Result := IsAppRespondingNT(GetWindowThreadProcessId(wnd,nil));
end;
Um das auf einem fremden PC umzusetzen, würde ich auf die Schnelle einen kleinen Dienst schreiben, der periodisch prüft, ob das Programm läuft und dann per TCP, Mail, UDP oder sonstwas Bescheid gibt, das was faul ist.

Käme auf einen Versuch an.

Leider ist die Funktion IsHungAppWindow nur für den internen Gebrauch und vielleicht auch gar nicht mehr so vorhanden.

Ich musste so einen Blödsinn mal schreiben, weil eine Anwendung aufgrund eines schrottigen Treibers manchmal abk*ckte und wir so wenigstens einen KillProcess-Versuch starten konnten. Letztendlich war das alles Blödsinn, aber es hat -soweit ich mich erinnern kann- funktioniert.

Luckie 6. Dez 2013 19:00

AW: Prüfen ob Programm abgestürzt ist
 
Zitat:

Zitat von taveuni (Beitrag 1238796)
Prüfen ob ein fremdes Programm abgestürzt ist - ist absolut unmöglich.

Und der Link den ich verlinkt habe? Scheint also doch möglich zu sein. Habe es mir aber noch nicht so genau angeguckt, ob da nicht doch ein haken bei ist.

Furtbichler 7. Dez 2013 06:44

AW: Prüfen ob Programm abgestürzt ist
 
"Abstürzen" ist natürlich so eine Sache.
Eine Anwendung kann den Dienst versagen, aber ganz brav auf sämtliche Messages reagieren. Trotzdem ist sie aus Sicht des Anwenders (andere App oder Benutzer) 'abgeschmiert'.
Ich finde die Aussage von taveuni auch etwas voreilig, zumal die Begründung
Zitat:

Zitat von taveuni (Beitrag 1238796)
Diesbezüglich haben wir schon Mannmonate investiert und schlussendlich aufgegeben.

etwas dürftig ist.
Die imho einzige Möglichkeit, einen Absturz zu erkennen, wäre ein periodischer Integrationstest, d.h. die Anwendung prüft selbst, ob die relevanten Komponenten noch funktionstüchtig sind und meldet das Ergebnis an einen Wächter. Bleibt die Meldung aus (oder ist eben negativ), wird entsprechend reagiert.

p80286 7. Dez 2013 10:41

AW: Prüfen ob Programm abgestürzt ist
 
Es wäre vllt. günstig erst einmal "abgeschmiert","Hängt",... zu definieren?
Aus meiner Erfahrung gibt es für "hängende" Anwendungen meist folgende Gründe:
a) Datenmenge einer Abfrage ist groß. Besonders Access schafft es gut sich tot zu stellen. Ebenso bei Abfragen wie
Code:
select irgendwas from table1,table2
brauchen Server einige Zeit um zu bemerken, daß die Datenmenge zu groß ist.
b) Ein Programm läßt ein Fenster aufpoppen, nur leider nicht "onTop" sondern "onBottom"
c) Eine Endlosschleife weil diese Datenkonstellation ja "nie" auftreten kann.

In allen diesen Fällen arbeitet das Programm "as designed", nur erwartet der Benutzer dies eigentlich nicht.

Gruß
K-H

EWeiss 7. Dez 2013 14:23

AW: Prüfen ob Programm abgestürzt ist
 
Man muss doch nur herausfinden wie Windows das selbst macht wenn ein Process hängt.
Dafür braucht man keinen Nobelpreis.

Denke das ist der Ansatz den auch Furtbichler verfolgt mit seinem Schnipsel.

gruss

BUG 7. Dez 2013 14:48

AW: Prüfen ob Programm abgestürzt ist
 
Zitat:

Zitat von EWeiss (Beitrag 1238867)
Man muss doch nur herausfinden wie Windows das selbst macht wenn ein Process hängt.
Dafür braucht man keinen Nobelpreis.

Aber es ist wichtig zu wissen, dass all diese Ansätze nur Heuristiken und bei Weitem nicht perfekt sind.
(Es gibt keine praktikable Möglichkeit festzustellen, ob ein Programm in einer (nicht gewollten) Endlosschleife hängt. Man kann aber zum Beispiel feststellen, ob es noch auf Nachrichten reagiert.)

Wenn man jetzt stark in einander integrierte hochverfügbare Anwendungen schreibt, kann man sicher noch andere Fortschritts-/Lebendigkeitseigenschaften überwachen.
Wenn iDope das wollen würde, hätte er vermutlich andere Fragen gestellt.

Olli73 7. Dez 2013 14:49

AW: Prüfen ob Programm abgestürzt ist
 
Zitat:

Zitat von EWeiss (Beitrag 1238867)
Man muss doch nur herausfinden wie Windows das selbst macht wenn ein Process hängt.

Gar nicht bzw. nicht korrekt. Ich weiß nicht wie oft Kunden schon ein Programm abgeschossen haben, nur weil Windows meldet "keine Rückmeldung".

Winodws meldet das aber nur aufgrund der Tatsache, ob das Programm seine Messages abarbeitet. Bei single threaded passiert das eben nicht, obwohl das Programm z.B. nur auf die Antwort eines DB-Servers wartet oder selbst noch am Rechnen ist. Bei multithreaded ist es dann genau umgekehrt.

Code:
loop
  TuWas;
until IrgendEineBedingung;
Wie entscheidest du ("von außen"), ob die Bedingung irgendwann erfüllt sein wird?

Furtbichler 7. Dez 2013 19:59

AW: Prüfen ob Programm abgestürzt ist
 
Der Umkehrschluss ist natürlich der, das man anfängt, diese Dinge in einen Thread auszulagern, eben damit Windows nicht mehr meckert,übrigens zu Recht: Es kommt von der Anwendung ja wirklich keine Rückmeldung.

Wenn man auf eine Datenbankabfrage wartet, dann muss man die eben auch abbrechen können. Wenn die Komponente das nicht hergibt, muss man eben eine andere nehmen.

Medium 8. Dez 2013 01:22

AW: Prüfen ob Programm abgestürzt ist
 
Nur hilft das überhaupt nicht, wenn man auf das zu überwachende Programm keinen Einfluss hat. Also im Sinne von selbst daran rumprogrammieren.

Fazit ist doch: Man kann gewisse Anzeichen von aussen als Hinweis interpretieren, dass ein Programm nicht mehr so läuft, wie es gedacht ist. Man kann damit allerdings auch sehr daneben liegen. Ob das so ist, ist von der Art und Weise abhängig, wie das zu überwachende Programm geschrieben ist. Eine allgemeingültige Lösung gibt es schlicht und ergreifend nicht. Und selbst wenn man das zu überwachende Programm selbst in der Hand hat, ist es noch immer recht schwierig. (Was bringt einem ein Life-Beat-Thread der einem Überwacher über z.B. TCP sein Vorhandensein mitteilt, wenn der eigentliche Arbeitsthread in einer Endlosschleife hängt z.B.? Solche Dinge müssten sehr gut durchdacht werden.)

Die Lösung des Problems ist hier daher davon abhängig, wie (und ob) man dem zu überwachenden Programm anerkennen kann, dass es gegen eine Wand gelaufen ist. Und zudem, ob dies aus einem fremden Prozess mit API Mitteln überhaupt ersichtlich werden kann. Ohne sehr genaue Kenntnis des Programms kann man daher imho nur ähnlich naive Methoden nutzen wie es Windows selbst macht, ohne jegliche Garantien auf Korrektheit der Absturzerkennung.

jaenicke 8. Dez 2013 08:48

AW: Prüfen ob Programm abgestürzt ist
 
Zitat:

Zitat von Smut (Beitrag 1238928)
Wie oft hatte ich das schon, das Windows 7 behauptet hat, ein Programm reagiere nicht mehr....
Manchma war es sogar von der gleichen Software Schmiede...
dann einfach noch ein bisschen gewartet... und hoppla es lief ja doch.

Das sind zwei verschiedene Sachen. Windows prüft ausschließlich, ob das Programm noch reagiert. Und da ist die Meldung auch absolut korrekt, wenn ein Programm nicht mehr reagiert. Das ist auch das Störende für den Bediener.

Wenn hingegen ein Programm länger läuft und dabei korrekterweise noch auf die GUI reagiert (Threads), erkennt Windows auch nicht, wenn der Vorgang an sich "abstürzt". Eben weil eine solche Absturzerkennung nicht möglich ist.

Ein Hängen im Sinne von nicht reagieren kann man jedenfalls einfach über die glaube ich schon genannte API Funktion herausfinden. Damit erkennt man das gleiche wie Windows selbst auch anzeigt. Wobei ich das mittlerweile nur noch bei wenigen kleineren Softwaretools als Problem habe. Die größeren Programme sind da besser und reagieren auch bei längeren Vorgängen noch.

hoika 8. Dez 2013 09:04

AW: Prüfen ob Programm abgestürzt ist
 
Hallo,

Da es ein fremdes Programm ist,
was zusätzlich auch noch im Netz läuft,
definiere ich "abgestürzt" einfach mit
"erfüllt seine Funktion nicht mehr so wie erwartet".

Das prüfe ich 5mal im Abstand von 1 Minute
und schieße es dann ab.

Heiko

Furtbichler 8. Dez 2013 09:50

AW: Prüfen ob Programm abgestürzt ist
 
Zitat:

Zitat von hoika (Beitrag 1238936)
...und schieße es dann ab....

... und starte es dann neu? :stupid:

Leider kann man nicht jedes Programm 'abschießen', vor allen Dingen gerade die, die 'hängen'.

Aber wenigstens hast Du das für dich definiert und hier kundgetan: Alle anderen reden nur um den heißen Brei herum

Delphi-Laie 8. Dez 2013 11:17

AW: Prüfen ob Programm abgestürzt ist
 
Zitat:

Zitat von Furtbichler (Beitrag 1238946)
Leider kann man nicht jedes Programm 'abschießen', vor allen Dingen gerade die, die 'hängen'.

Wohl nicht auf die Weise, die der Taskmanager unter "Anwendungen" als "Task beenden" anbietet. Das ist nach meinem Wissen nicht mehr als eine an das Progremm verschickte Beenden-Bitte. Programme, die sich verschließen, werden darauf demnach nicht anders als "verzickte" Menschen reagieren. Besser ist schon "Prozess beenden" unter dem Reiter "Prozesse", das beruht m.E. auf TerminateProcess. Besonders groß dürfte die Erfolgsaussicht sein, wenn man das mit erweiterten Prviilegien tut (erfordert Administratorrechte). Mein Programm "Prozesse" (auch in diesem Forum unter "Prozeßbetrachter" zu finden) demonstriert das.

Allerdings stößt auch TerminateProcess irgendwann an seine Grenzen, und zwar bei Diensten und den "besonders systemnahen Prozessen".

Ergänzung: "Besonders systemnahe Prozesse" setzte ich deshalb in Anführungsstriche, weil mir noch ein glanzvoller Beitrag von Assarbad "im Hinterkopf" bekannt und bewußt war, den ich nun wiederfand: http://www.delphipraxis.net/1057551-post10.html

himitsu 8. Dez 2013 11:24

AW: Prüfen ob Programm abgestürzt ist
 
Zitat:

Zitat von Delphi-Laie (Beitrag 1238962)
Allerdings stößt auch ProcessTerminate irgendwann an seine Grenzen, und zwar bei Diensten.

Nur wenn da die nötigen Rechte fehlen. (Anwender/Taskmanager = Benutzer und Dienst ist Systemdienst)

Aber bei hängenden Treibern (nicht User-Mode-Treibern) wartet ProcessTerminate auch gern auf den Treiber.



Also:
- Windows prüft nur, ob die GUI hängt, aber kann nicht prüfen ob das Programm hängt

- was "Hängen" ist, muß je nach Anwendung/Funktion/Verwendung entsprechend definiert werden

- es ist nicht immer möglich auf das "Hängen" zu prüfen

- praktisch kann man nur regelmäßig versuchen eine "Aktion" auszulösen und deren "Ergebnis" auswerten, um das "Hängen/Funktionieren" prüfen zu können,
aber auch das ist nicht immer ein sichere Prüfmethode (z.B. Funktionsaufruf geht, das Ergebnis ist valide, aber es stimmt nicht "mehr", weil eine Aktualisierungsroutine hängt)

- usw.

jaenicke 8. Dez 2013 11:43

AW: Prüfen ob Programm abgestürzt ist
 
Zitat:

Zitat von Delphi-Laie (Beitrag 1238962)
Wohl nicht auf die Weise, die der Taskmanager unter "Anwendungen" als "Task beenden" anbietet. Das ist nach meinem Wissen nicht mehr als eine an das Progremm verschickte Beenden-Bitte.

Aber danach wird auch angeboten das Programm hart zu beenden, wenn es auf die Message mit der Anforderung nicht reagiert. Deshalb ist der Weg schon der sinnvollste, wenn man nicht zu 100% sicher ist, dass das Programm ohnehin nicht reagieren wird. Denn wenn es doch noch darauf reagiert und nur die GUI gerade eingefroren ist, wird es dann sanft beendet und kann dabei aufräumen.

Hart beenden sollte man nur, wenn der sanfte Weg nicht klappt.

Furtbichler 8. Dez 2013 19:19

AW: Prüfen ob Programm abgestürzt ist
 
Zitat:

Zitat von Delphi-Laie (Beitrag 1238962)
Zitat:

Zitat von Furtbichler (Beitrag 1238946)
Leider kann man nicht jedes Programm 'abschießen', vor allen Dingen gerade die, die 'hängen'.

:::Besser ist schon "Prozess beenden" unter dem Reiter "Prozesse", das beruht m.E. auf TerminateProcess. Besonders groß dürfte die Erfolgsaussicht sein, wenn man das mit erweiterten Prviilegien tut (erfordert Administratorrechte)....

Witzbold ;-) Wenn ich sage 'geht nicht', dann meine ich natürlich auch 'geht nicht'. Weder mit Adminrechten, noch als Prozess, noch sonstewie.

Zitat:

Zitat von himitsu (Beitrag 1238966)
Aber bei hängenden Treibern (nicht User-Mode-Treibern) wartet ProcessTerminate auch gern auf den Treiber.

Und wenn der Treiber schrott ist, dann wartet ProcessTerminate eben bis in alle Ewigkeit => 'geht nicht'

iDope 10. Dez 2013 11:02

AW: Prüfen ob Programm abgestürzt ist
 
Okay, das ist ja ein ziemlich heikles Thema was ich hier angestoßen habe.
Und wie das hier aussieht ist genau das was ich vor hatte gar nicht bzw nicht in diesem Ausmaß möglich, wenn ich mir hier die Kommentare durchlese.
Trotzdem vielen Dank für eure Hilfe, ich versuche eine andere Lösung des Problems zu finden.
Falls jemand jedoch eine Lösung, die mein Problem behebt, findet, die eventuell noch nicht angesprochen wurde, wäre es nett diese hier zu posten (:

MfG
iDope


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:36 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz