Update mittels nUpdate - Code im Form.Closed Event ausführen

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

Es gibt 23 Antworten in diesem Thema. Der letzte Beitrag () ist von DerSmurf.

    Update mittels nUpdate - Code im Form.Closed Event ausführen

    Ich nutze zum updaten meines Programmes nUpdate von @Trade
    In meinem Programm ist es so, dass das DataSet beim verlassen der Anwendung im Form.Closed Event gespeichert wird.

    VB.NET-Quellcode

    1. Private Sub FrmMainForm_Closed(sender As Object, e As EventArgs) Handles Me.Closed
    2. SaveSettings()
    3. End Sub

    Wenn ich allerdings mit nUpdate nach Updates suche und eines gefunden wird, welches ich einspiele. So wird das Form.Closed Event nicht erreicht.
    Mein Programm wird beendet, ohne Speicherung des DateSets - das ist natürlich doof.
    Mir fällt jetzt nur die Lösung ein meine Updatesuche um eine Speicherfunktion zu ergänzen. Allerdings funktioniert dies ja nur solange, wie mein DataSet noch recht klein ist und ohne merkliche Verzögerung auf die Platte geschrieben werden kann.
    Ist also eher eine Notfalllösung.
    Gibt es hier einen anderen Weg?

    So sieht die Update Suche aus:

    VB.NET-Quellcode

    1. Private Sub TSUpdate_Click(sender As Object, e As EventArgs) Handles TSUpdate.Click
    2. Dim manager As New UpdateManager(New Uri("URL etfernt", New CultureInfo("de-DE"))
    3. Dim updaterUI As New UpdaterUI(manager, SynchronizationContext.Current)
    4. updaterUI.ShowUserInterface()
    5. End Sub
    @DerSmurf Wie sieht denn das Beenden der Form aus?
    Kannst Du von dem Updater ein Event an die Form senden, wo dann gespeichert wird?
    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!
    @DerSmurf Wie wird denn die Beendigung des Programms durchgeführt?
    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 kann ich dir leider nicht sagen, da ich es nicht schaffe den nUpdate Prozess schrittweise durchlaufen zu lassen.
    Da allerdings das Form.Closed Event nicht erreicht wird (das weiß ich sicher), vermute ich, dass innerhalb nUpdates ein beenden des Programmes mittels Application.Exit - oder vergleichbarem stattfindet.
    Denn letzlich muss ja auch gesichert sein, dass sich das Programm ohne murren beendet, wenn der User auf den Update Button drückt.
    Hi,

    dafür ist die Methode TerminateApplication im UpdateManager überschreibbar.
    Bau Dir eine Klasse so und verwende diese dann in Deinem TSUpdate_Click statt dem UpdateManager in Deinem Code:

    VB.NET-Quellcode

    1. Public Class CustomUpdateManager Inherits UpdateManager
    2. ' Konstruktor hier deklarieren
    3. Public Sub New(...)
    4. MyBase.New(...)
    5. End Sub
    6. Public Overrides Sub TerminateApplication()
    7. Application.Exit()
    8. End Sub
    9. End Class


    Kurze Info dazu: Standardmäßig ruft nUpdate hier Environment.Exit(0) auf, was keine Form-Handler mehr ausführt. Application.Exit() tut dies schon. Falls die Anwendung dann nicht richtig schließt, bau Dir eine ausgelagerte Routine für das Speichern des DataSets und rufe diese dort stattdessen gefolgt von der Basismethodenimplementierung auf. Glaube aber nicht, dass das notwendig ist.
    Der Quellcode von nUpdate ist btw auf GitHub verfügbar. Den kannst Du also durchaus in Visual Studio öffnen und bearbeiten (PDB-Dateien sollten auch beim Debuggen helfen). In dem Fall aber nicht benötigt.

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Wenn Du mir sagst, wo es hängt. Den Code habe ich Dir ja bereitgestellt.

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Es tut mit leid, aber ich habe noch nie mit Konstruktoren (oder Klassen in dieser Art) gearbeitet.
    Soll heißen, ich habe keine Ahnung mit welchen Parametern ich die "(...)" füllen soll.

    Außerdem bekomme ich zwei Fehlermeldungen. Hier weiß ich aber natürlich nicht, ob diese am fehlenden Konstruktor liegen.

    In der Deklaration der Klasse ​Public Class CustomUpdateManager Inherits UpdateManager meckert VS bei Inherits mit "End of Anweisung erwartet".
    Bei der Sub ​ Public Overrides Sub TerminateApplication() die Fehlermeldung, dass diese nicht als Override deklariert werden könne, da es kein Sub in einer Basisklasse überschreibt.

    Ich habe eine neue Klasse erstellt, die ich CustomUpdateManager genannt habe. Dort habe ich deinen gesamten Code einkopiert.
    @DerSmurf Wenn Du Deinen Code dazu postest, sollte es ein Klax sein.
    Wahrscheinlich fehlt bei Dir ein End Class.
    Und aus Public Overrides Sub TerminateApplication() machst Du Public Sub TerminateApplication().
    Allerdings kann es sein, das es da iwelche anderen ähnlich klingenden Prozeduren gibt, da musst Du mal ansehen, was da so angeboten wird, wenn Du Public Overrides LEERZEICHEN eingibst.
    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 Overrides ist schon richtig. Vermutlich meckert Visual Studio, weil die Vererbungsbeziehung durch den ersten Fehler nicht korrekt analysiert wurde.
    Aber muss dazu sagen, ich habe schon Jahre kein VB.NET mehr angefasst. :D

    @DerSmurf Die Parameter sind genau dieselben wie die des UpdateManagers: github.com/dbforge/nUpdate/blo…ting/UpdateManager.cs#L65

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Das muss heißen Public Class CustomUpdateManager : Inherits UpdateManager. Also mit Doppelpunkt. Oder das Inherits UpdateManager in die nächste Zeile.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Ah, stimmt. So war das, danke. Komische Syntax. :huh:

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Ich danke euch.
    Bin ein gutes Stück weiter. Die Fehler sind weg. Außer in MyBase.New(...).
    Hier wird mir updateConfigurationFileUri[b] As Uri,[/b] "Komma, oder gültige Ausdruckfortsetzung erwartet" angezeigt.
    publicKey As String, hier das selbe
    Optional languageCulture As CultureInfo = Nothing, Ausdruck erwartet
    Optional currentVersion As UpdateVersion = Nothing) - Ausdruck erwartet.

    Was hab ich hier falsch verstanden?
    Edit: herausgefunden. Hier muss das hin was ich sonst beim Aufruf von nUpdate mitgebe:
    ​ Dim manager As New UpdateManager(New Uri("...)
    Aber dann habe ich den Aurfuf nicht verstanden.
    Letztlich muss ich ja jetzt nur anstelle meiner Zeile:
    ​Dim manager As New UpdateManager(New Uri("http...) auf den CustomUpdateManager verweisen. Also ​Dim manager As New CustomUpdateManager(New Uri("http:/...)
    Aber dann habe ich ja an dieser Stelle und in MyBase.New der CustomUpdateManager Klasse die gleichen Parameter. Das kann ja irgendwie nicht korrekt sein :(

    und ich müsste wissen ob ich Public Sub New(...) - korrekt in vb.net übersetzt habe. (der Compiler hat immerhin nix zu meckern)

    VB.NET-Quellcode

    1. Imports System.Globalization
    2. Imports nUpdate.Updating
    3. Public Class CustomUpdateManager : Inherits UpdateManager
    4. 'Konstruktor hier deklarieren
    5. Public Sub New(updateConfigurationFileUri As Uri, publicKey As String, Optional languageCulture As CultureInfo = Nothing, Optional currentVersion As UpdateVersion = Nothing)
    6. MyBase.New(updateConfigurationFileUri As Uri, publicKey As String, Optional languageCulture As CultureInfo = Nothing, Optional currentVersion As UpdateVersion = Nothing)
    7. End Sub
    8. Public Overrides Sub TerminateApplication()
    9. Application.Exit()
    10. End Sub
    11. End Class

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

    @DerSmurf Wenn das New dieselbe Signatur hat wie MyBase.New dann kannst Du den ansonsten leeren Konstruktor weglassen.
    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!
    Und kurz zur Aufklärung: Die Datentypen kommen nicht in den Aufruf:
    Statt

    VB.NET-Quellcode

    1. Public Sub New(updateConfigurationFileUri As Uri, publicKey As String, Optional languageCulture As CultureInfo = Nothing, Optional currentVersion As UpdateVersion = Nothing)
    2. MyBase.New(updateConfigurationFileUri As Uri, publicKey As String, Optional languageCulture As CultureInfo = Nothing, Optional currentVersion As UpdateVersion = Nothing)
    3. End Sub

    schreib

    VB.NET-Quellcode

    1. Public Sub New(updateConfigurationFileUri As Uri, publicKey As String, Optional languageCulture As CultureInfo = Nothing, Optional currentVersion As UpdateVersion = Nothing)
    2. MyBase.New(updateConfigurationFileUri, publicKey, languageCulture, currentVersion)
    3. End Sub

    Aber RfG schrieb ja bereits: Kannste auch weglassen. Wenn in der Klasse nix zu finden ist, sucht der Compiler die Infos in der Basisklasse.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Dass ich MyBase.New einfach weglasse kam mir auch schon in den Sinn. Deswegen hab ichs mal auskommentiert.
    Allerdings meckert der Compiler dann bei Public Sub New:
    "Die erste Anweisung dieser "Sub New" muss ein Aufruf an "MyBase.New" oder "MyClass.New" sein, da die Basisklasse "UpdateManager" von "CustomUpdateManager" keine zugreifbare "Sub New" hat, die ohne Argumente aufgerufen werden kann."
    Also habe ich jetzt den Code von @VaporiZed verwendet. Dieser funktioniert. Es wird nun beim Update "meine" neue Klasse CustomeUpdateManager verwendet.
    Jedoch erfüllt diese nicht ihren Zweck. Das Form.Closed Event wird nach wie vor nicht gefeuert.
    Die neue Sub in der CustomUpdateManager Klasse wird aber erreicht:

    VB.NET-Quellcode

    1. Public Overrides Sub TerminateApplication()
    2. Application.Exit()
    3. End Sub

    scheinbar veranlasst Application.Exit aber nicht das Form.Closed Event.

    Trade schrieb:

    Falls die Anwendung dann nicht richtig schließt, bau Dir eine ausgelagerte Routine für das Speichern des DataSets und rufe diese dort stattdessen gefolgt von der Basismethodenimplementierung auf.

    Eine ausgelagerte SaveSub gibt es bereits:

    VB.NET-Quellcode

    1. Private Sub FrmMainForm_Closed(sender As Object, e As EventArgs) Handles Me.Closed
    2. SaveSettings()
    3. End Sub

    Wenn ich nun vor Application.Exit in ​Public Overrides Sub TerminateApplication() SaveSettings() ausführe ist doch alles gut?
    Was meinst du mit "... gefolgt von der Basismethodenimplementierung auf"

    und warum kann ich das Programm an dieser Stelle nicht einfach "sauber" beenden. Statt Application.Exit, Me.Close verwenden?

    DerSmurf schrieb:

    Dass ich MyBase.New einfach weglasse kam mir auch schon in den Sinn.
    Das wäre fatal!

    VB.NET-Quellcode

    1. Sub New(i As Integer)
    2. MyBase(i)
    3. End Sub
    ist was völlig anderes als

    VB.NET-Quellcode

    1. Sub New(i As Integer)
    2. 'MyBase(i)
    3. End Sub
    weil der Konstruktor in der Basisklasse da nicht aufgerufen wird.
    Wenn, dann bitte so:

    VB.NET-Quellcode

    1. 'Sub New(i As Integer)
    2. ' MyBase(i)
    3. 'End Sub
    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!