Konsolenanwendung - System Shutdown Event

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Konsolenanwendung - System Shutdown Event

    Hi,
    ich brauche für meine Konsolenanwendung ein Event, welches beim schließen, genauer gesagt beim Herunterfahren des Systems gefeuert wird.
    Alles, was ich bis her probiert habe hat einfach nicht funktioniert, das heißt, es ist überhaupt nicht passiert.

    Meine Versuche:

    VB.NET-Quellcode

    1. AddHandler SystemEvents.SessionEnding, Sub(s, e)
    2. IO.File.WriteAllText("C:\hallo.txt", DateTime.Now.ToString())
    3. End Sub


    VB.NET-Quellcode

    1. AddHandler AppDomain.CurrentDomain.ProcessExit, Sub(s, e)
    2. IO.File.WriteAllText("C:\sds.txt", DateTime.Now.ToString())
    3. End Sub


    Spoiler anzeigen

    VB.NET-Quellcode

    1. <DllImport("Kernel32")> _
    2. Public Function SetConsoleCtrlHandler(Handler As HandlerRoutine, Add As Boolean) As Boolean
    3. End Function
    4. Public Delegate Function HandlerRoutine(CtrlType As CtrlTypes) As Boolean
    5. Public Enum CtrlTypes
    6. CTRL_C_EVENT = 0
    7. CTRL_BREAK_EVENT
    8. CTRL_CLOSE_EVENT
    9. CTRL_LOGOFF_EVENT = 5
    10. CTRL_SHUTDOWN_EVENT
    11. End Enum
    12. Private Function ConsoleCtrlCheck(ctrlType As CtrlTypes) As Boolean
    13. IO.File.WriteAllText("C:\test123.txt", DateTime.Now.ToString())
    14. Return True
    15. End Function
    16. Dim hr As New HandlerRoutine(AddressOf ConsoleCtrlCheck)
    17. GC.KeepAlive(hr)
    18. SetConsoleCtrlHandler(hr, True)


    Es wurde kein einziges mal eine Text-Datei erstellt. Hat noch jemand ne Idee oder weiß, wieso nichts davon funktioniert?
    Mfg
    Vincent

    VincentTB schrieb:

    wieso nichts davon funktioniert?
    Hast Du es mal mit einer WinForm-Anwendung probiert?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @HamburgerJungeJr
    Es kann doch nicht sein, dass eine Konsolenanwendung so "beschränkt" ist, dass sie nicht mal ein Closing-Event besitzen kann, oder?

    @RodFromGermany
    Gerade gemacht, da funktioniert es. Aber ich bräuchte es, wenn möglich, für eine Konsolenanwendung (wäre zumindest ganz schön, werde aber wohl oder übel auf WinForms wechseln müssen, wenn niemand anders ne Idee hat...)
    Mfg
    Vincent

    Fang an und bring einer

    VincentTB schrieb:

    Konsolenanwendung
    ühaupt Events bei.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hi
    bitte @RodFromGermany, es wäre sehr nett, wenn du mehr, als nur immer einen Brösel in Threads hinterlassen könntest, der nahezu Spam ist, aber gerade nicht mehr. Wenn man sich fast immer aus den Fingern saugen muss, was du genau sagen willst, bringt dein Hilfeversuch relativ wenig, wenn auch nett gemeint. Schreib' einfach mehr oder zumindest so, dass man weiß, worauf du hinaus willst. Würdest du das machen, wärst du sicherlich nicht bei der Masse an Beiträgen, würde man jeden Beitrag löschen, der auf die oben genannte Kategorie passt, würde man vmtl. auf noch weit weniger kommen.

    Hast du das hier probiert?

    VB.NET-Quellcode

    1. AddHandler Microsoft.Win32.SystemEvents.SessionEnded, _
    2. Sub(s, e)
    3. If e.Reason = Microsoft.Win32.SessionEndReasons.SystemShutdown Then
    4. End If
    5. End Sub

    Das größte Problem dürfte sein, dass die Konsole den Anschein gibt, dass die Anwendung "freezt", ggf. kannst du aus dem Event heraus die Konsole signalisieren.

    Edit: Das Konsolenevent CancelKeyPress wird vmtl. nicht gefeuert, oder?

    Gruß
    ~blaze~

    ~blaze~ schrieb:

    Brösel

    @VincentTB
    Füge einer Konsole einene Event hinzu, von dem mit Sicherheit klar ist, dass er gefeuert wird (ich habe keinen parat).
    Wenn das funktioniert, taste Dich an die unsicheren heran.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Das ist schon besser. Wäre toll, wenn du es bei sowas belassen könntest :) .
    Warum aber sollte das ein Problem darstellen? Ich würde darauf tippen, dass das System die Anwendung beendet, weil es davon ausgeht, dass die Anwendung inaktiv ist - wartet ja die ganze Zeit auf Input oder sonst was. Es gäbe schon die Möglichkeit, einen "Hybrid" zwischen Konsole und Windows Forms Anwendung zu schreiben, z.B. über ApplicationContext und System.Windows.Forms.Application.Run und dort das Ende der Nachrichtenschleife abzuwarten, aber ich zweifle daran, dass das die beste Lösung ist.
    Was genau ist das eigentlich für eine Anwendung?

    Gruß
    ~blaze~
    @~blaze~
    #1 Nö, funktioniert auch nicht

    #2 Ich denke, so wichtig war die Konsole dann doch auch nicht. Habe jetzt ne WinForms Anwendung genommen, wo alles perfekt funktioniert.

    @RodFromGermany
    Nen paar mehr Informationen wäre manchmal wirklich ganz schön :)
    Durch die Verwendung der WinForms-Anwendung hat sich das damit auch geklärt, ich würde fast tippen, dass es ohne ne menge Aufwand relativ schwierig ist, auf die Events in einer Konsolenanwendung zu reagieren. (scheint auch niemand zu brauchen, zumindest steht im Internet fast nichts darüber oder ich habe schlecht gesucht).
    Mfg
    Vincent

    Es wäre ggf. auch eine Idee, das immer mal wieder zu speichern, nachdem Änderungen stattgefunden haben. Sprich: Daten in einem Cache halten und den Cache irgendwann rausschreiben, z.B. 5 Sekunden nach einer Änderung oder sofort, nachdem die Konsole wieder in einen Idle-Zustand gehen würde. Multithreading wäre im Allgemeinen auch keine schlechte Idee bei sowas. Wenn dir Windows Forms genügen, ist's auch okay, aber ich hatte bei meinem... QuickDrop-Projekt das gleiche Problem.

    Gruß
    ~blaze~
    @VincentTB Eine Console-Anwendung ist der Sache nach keine event-gesteuerte Anwendung.
    Sie hat mit main() einen wohldefinierten Eintrittspunkt und einen Ausstieg beim Verlassen von main.
    Dazwischen ist linearer Spagetticode.
    Um in einer Console auf ein Event reagieren zu können, musst Du so was wie eine Queue-abarbeitende Loop bauen, in der auf Events reagiert werden kann. Da kannst Du auch gleich ne WinForm nehmen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Um in einer Console auf ein Event reagieren zu können, musst Du so was wie eine Queue-abarbeitende Loop bauen, in der auf Events reagiert werden kann. Da kannst Du auch gleich ne WinForm nehmen.

    Meiner Meinung nach kompletter Bullshit. Mit ner Konsole kannst du schlichtweg so gut wie alles machen. Es kommt sich drauf an mit was du sie füllst. Für Events in einer Konsole brauche ich sicher garantiert keine Winforms Anwendung. Immerhin kannst du Threads starten, events deklarieren so viele du willst,... Was brauche ich da Winforms. Winforms ist für ne GUI.

    Btw. Herunterfahren blockieren: msdn.microsoft.com/en-us/libra…op/aa376877(v=vs.85).aspx


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    Um auf so ein Event zu reagieren musst du ne Message Queue implementieren, sowas ist bei Winforms halt einfach schon drin. Btw: nach msdn.microsoft.com/de-de/libra…sionending(v=vs.110).aspx
    Konsolenanwendungen lösen das SessionEnding-Ereignis nicht aus.
    weil eben so eine Message Queue fehlt.

    ​Btw. Herunterfahren blockieren: msdn.microsoft.com/en-us/libra…op/aa376877(v=vs.85).aspx
    Geht mit reiner Console auch nicht, brauchst ja als ersten Parameter en Handle zum Fenster und dazu brauchste entweder Winforms oder erstellst man per WinApi en Fenster, was man sich ja sparen kann.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „rykoJLL“ ()

    thefiloe schrieb:

    so gut wie alles machen.
    Natürlich.
    Aber das ist im Prinzip so, als ob Du aus einer TextBox eine RichTextBox machen wolltest, Du musst Dich um jeden Sch... selber kümmern, der in der WinForm bereits da ist.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Gonger96 schrieb:

    Dazu brauch ich weder Queue
    Sobald Du in einer Schleife die Tastatur abfragst, um zu verhindern, dass sich die Console selbst beendet, hast Du bereits eine Queue.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    rykoJLL schrieb:

    Geht mit reiner Console auch nicht, brauchst ja als ersten Parameter en Handle zum Fenster und dazu brauchste entweder Winforms oder erstellst man per WinApi en Fenster, was man sich ja sparen kann.

    Ach ja. Für ein Handle braucht man also Winforms? Jedes Fenster, einfach alles auf Windows hat nen Handle. Und eine Konsole ist auch ein Fenster -> hat ein Handle.

    RodFromGermany schrieb:

    Du musst Dich um jeden Sch... selber kümmern, der in der WinForm bereits da ist.

    Wenn es um GUI geht ja. Wenn ich jedoch z.B. einen Server als Konsole schreibe, dort Events verwende dann werde ich sicherlich keine Buttons brauchen. Da bringt mir Winforms nen "Sch...".


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.

    RodFromGermany schrieb:

    Sobald Du in einer Schleife die Tastatur abfragst, um zu verhindern, dass sich die Console selbst beendet, hast Du bereits eine Queue.

    Das ist schön, braucht man aber nicht. Hat man zwar oft, aber für Events ist das nicht zwingend notwendig.