Konsolenanwendung



  • prüf mal was terminate zurückgibt, im falle von 0 ruf GetLastError auf und prüfe die rückgabe, die fehlercodes findest mit bissl suchen im web aber ich schau auch gern für dich in meine borland-hilfe :p

    The handle must have the PROCESS_TERMINATE access right. For more information, see Process Security and Access Rights.

    [...]

    The handle returned by the CreateProcess function has PROCESS_ALL_ACCESS access to the process object. When you call the OpenProcess function, the system checks the requested access rights against the DACL in the process's security descriptor. When you call the GetCurrentProcess function, the system returns a pseudohandle with the maximum access that the DACL allows to the caller.

    You can request the ACCESS_SYSTEM_SECURITY access right to a process object if you want to read or write the object's SACL. For more information, see Access-Control Lists (ACLs) and SACL Access Right.

    [cpp]
    HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
    PROCESS_VM_READ |
    PROCESS_TERMINATE,
    FALSE, pid );
    [/cpp]

    WTH? die cpp tags gehn nit 😮



  • herzlichen Dank, Ceos, das war tatsächlich nur der kleine flag.
    Jetzt geht's wunderbar.



  • trotzdem, wenns sauber beendet werden soll und der task nit hängt sondern einfach nur ausgemacht werden soll, versuchs mit

    BOOL PostMessage(          HWND hWnd,
        UINT Msg,
        WPARAM wParam,
        LPARAM lParam
    );
    

    und sende ein WM_USER+x signal um dem task freundlich mitzuteilen er solle beenden _ (also sein ExitProcess() selber aufrufen)

    PS: klappt natürlich nur wenn du zugriff auf die quellcodes der tasks hast die su startest

    PPS: auch wenns verlockend einfach aussieht poste NIEMALS WM_QUIT

    hier noch ein auszug, der dir eventuell gefahrenquellen vor augen führt

    Terminating a process causes the following:

    All of the object handles opened by the process are closed.
    All of the threads in the process terminate their execution.
    The state of the process object becomes signaled, satisfying any threads that had been waiting for the process to terminate.
    The states of all threads of the process become signaled, satisfying any threads that had been waiting for the threads to terminate.
    The termination status of the process changes from STILL_ACTIVE to the exit value of the process.

    Terminating a process does not cause child processes to be terminated.

    Terminating a process does not necessarily remove the process object from the operating system. A process object is deleted when the last handle to the process is closed.

    Warning Calling ExitProcess in a DLL can lead to unexpected application or system errors. Be sure to call ExitProcess from a DLL only if you know which applications or system components will load the DLL and that it is safe to call ExitProcess in this context.



  • herzlichen Dank,Ceos, für die Geduld.

    Dass es etwas unsaubere Angelegenheit ist, ist mir schon bewusst. Aber tatsächlich ist es so etwas wie ein Notprogramm, das einen dauerhaften Betrieb gewährleisten soll - und gerade dann, wenn ein (Konsolen-)Programm sich aufgehängt hat.

    Da schließt sich die Frage an: Wie lässt sich abfragen, ob ein Programm anstandslos läuft. ich habe irgendwo gelesen, dass es in regelmäßigen Abständen "Meldung machen muss", ansonsten gilt es als abgestürzt.



  • Da gibt's keinen allgemeingültigen Ansatz (das Problem läuft auf's Halteproblem hinaus - und das ist nicht entscheidbar), also mußt du eine eigene Strategie entwickeln. Das Zielprogramm zu fragen, ob es noch lebt, ist da ein guter Ansatz (wenn du selber Einfluß auf das Zielprogramm hast).

    (btw, die Lösung verwendet auch der Windows-Taskmanager - er schickt eine Nachricht an das Programm und wenn es nach 5 Sekunden nicht reagiert hat, blendet er "keine Rückmeldung" ein)



  • Interessant.
    Hat mich dazu gebracht, auf eine absolute brute force - Methode zu setzen. Also:
    die Konsolenapplikation schreibt einen Timestamp in eine Datei. Ist dieser um einen gewissen Betrag älter als der aktuelle Timestamp, wird sie als abgestürzt betrachtet.
    Oder ist auch dies eine Absturzgefahrenquelle?

    Danke nochmal an alle.



  • Doch noch eine Nachfrage:

    Die Technik mit dem timestamp funktioniert ganz gut (sie hat mich bislang jedenfalls vor Ausflügen in die pipe-Programmierung bewahrt), nichtsdestoweniger tut sich ein Problem auf.

    Wenn ein Konsolenprogramm abstürzt, kommt diese Meldung: fatal application error, die eine Bestätigung über die OK Taste verlangt.

    Wenn das Programm nun über TerminateProcess den Prozess beendet, bleibt mir dieses (Child-)Window fatalerweise erhalten. Wie werde ich das los?

    Hat das nicht die gleiche pid wie der Konsolenprozess selbst?



  • ich habe jetzt eine ganze Reihe von Techniken ausprobiert, wie etwa:

    http://support.microsoft.com/default.aspx?scid=KB;en-us;q178893

    aber eine abgestürzte Kosolenanwendung lässt sich einfach nicht mit den gängigen Techniken entfernen. Wenn das Dialogfenster erscheint, so scheint dies das Durchkämmen der Prozesse zu blockieren.

    EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
    etwa gibt mit dann stets 0 Einträge zurück-

    Hat jemand eine Lösung parat?



  • das iss genau das was ich gemeint hatte, es kann gut und gern passieren das der prozess trotz terminate erhalten bleibt, liegt wohl daran das mit erscheinender dialogbox auch der handle noch referenziert wird ... und laut der hilfe kann der prozess dann nicht vernünftig beendet werden



  • Ceos, ich habe (zumindest bin ich noch guter Hoffnung) unterdes eine Lösung gefunden. Wenn man das Flag NO_CREATE_WINDOW setzt, so hat man den reinen Prozess, der sich wiederum über TerminateProcess beenden lässt. Scheint wirklich, dass das blöde Konsolenfenster den Stolperstein bildet.



  • na denn wünsch ich viel erfolg, schreib mal was am ende rausgekommen ist, du hast mich da nämlich auch auf ne idee gebracht



  • Bislang sieht das Ergebnis ganz gut aus. Eine Art Metaobjekt, das vier (jetzt unsichtbare) Konsolenprogramme überwacht, die ihrerseits Serverfunktionen haben.
    Da das eine oder andere fehlerbehaftet ist, ist es bislang immer zu Abstürzen gekommen - die auch deswegen so blöd sind, weil die Programme untereinander kommunizieren und jeder Absturz den Gesamtmechanismus blockiert. Jetzt läuft es seit 12 Stunden brav.

    Die Technik mit dem timestamp scheint wirklich ganz gut. Alle paar Sekunden gibt das (unsichtbare) Konsolen-Programm ein "Lebenszeichen" von sich - und das Meta-Programm fragt nur die Zeit ab. Das Löschen (per TerminateProcess, oder auch mit einem "sauberen" Microsoft-Löschbefehl) funktionert, und der CreateProcess ohne GUI scheint das Hauptporoblem beseitigt zu haben.

    Eigentlich ist es ja auch ganz logisch: Das Fenster, das den User über den Absturz der Anwendung informiert, wird wohl nicht die pid des abgestürzten Programms haben, sondern wird wohl ein eigenständiges Objekt sein (eines, das darüberhinaus enumerate Processes blockiert). Ich stochere da ziemlich im Nebel, denn die ganze Thematik ist mir noch ziemlich neu.


Anmelden zum Antworten