Batch nach Programmende aufrufen

  • VB.NET

Es gibt 24 Antworten in diesem Thema. Der letzte Beitrag () ist von Westerwälder.

    Batch nach Programmende aufrufen

    Hallo,

    habe da ein kleines Problem und zwar arbeite ich ohne eine Installer für mein Programm. Funktioniert auch alles soweit. Nur komme ich bei der Deinstallation nicht weiter. Die Exe Datei und auch der Pfad der Exe sollen nach der Deinstallation gelöscht sein. Habe eine Batchdatei im Sinn, die dieses nach Verlassen der Deinstallation und Beendigung der Anwendung aufruft. Oder gibt es da event. eine andere Lösung?
    Gruß Markus
    Erstelle doch beim Installer einen Registry-Eintag mit Programmpfad/Pfad zur exe hinzu, frag diesen bei der deinstallation ab, lösche die dateien/ordner und zum schluss den Registry-Eintrag.
    Schau dir dazu den My.Computer.Registry-Namespace an.
    MfG, Live
    --- Zurzeit inaktiv ---
    für besseren Support empfehle ich eher .vbs ;) oder für die Performance .cmd

    du kannst ganz einfach (mMn auch bei Skripten) den 1. Parameter nehmen und daraus den Pfad auslesen und man hat den Ordner wo es gestartert wurde und dort alles löschen (bis auf Settings o.Ä. wichtiges)
    Danke für die Vorschläge. Bin relativ neu in VB.Net. Habe vor vielen Jahren kommerziell in GWBasic programmiert, was hier nicht sehr hilfreich ist. Nun bin ich frühverrentet worden und suche in der Programmierung wieder eine vernünftige Aufgabe (Nicht kommerziell). Aber nun zum eigentlichen Problem. Mein Programm hat ein Programmpfad und einen Datenpfad. Die Löschung des Datenpfades erledigt die Deinstalltionsroutine des Programmes. Auch die Ini.Datei und sonstige mitgegebenen Dateien im Programmpfad lösche ich bereits in der Deinstalltionsroutine, sodass nur noch die Anwendung.exe übrig bleibt. An die Registrierung von Windows traue ich mich nicht wirklich ran. Die Lösung mit einer Batchdatei wäre mir am liebsten, da mir das Prinzip bekannt ist. Stelle mir vor, dass die Dinstalltionsroute die Batch selbst erstellt. Nur wie kann ich der Anwendung mitteilen, dass sie normal geschlossen wurde --- kein Auftruf der Batch --- oder das sie nach Ausführung der Deinstalltion --- Aufruf der Batch --- geschlossen wurde?
    Gruß Markus
    Das kommt darauf an, wie die Anwendung deinstalliert werden soll.
    Gibt es in der Anwendung einen Button - "Deinstallieren" oder wie ist da deine Herangehensweise.
    Prinzipiell ist dies ja ein einfacher Boolean Wert, den man setzen kann.
    (zB -> Deinstallationsroutine startet, setzt eine globalen Boolwert namens CreateBatch oder wie auch immer auf True).
    Im CloseEvent der Form (falls du eine benutzt) erstellst du die Batch, wenn der Bool True ist und führst diese aus.

    Gruss Mono
    Das ist meine Signatur und sie wird wunderbar sein!
    Hallo,

    ja der Deinstallationsauftrag wird durch ein Clickevent ausgelöst und ruft dann die Sub Programm_Deinstallieren auf. Sicherlich kann ich das FormClose Event abfragen, aber die Anwendung läuft ja da noch. Kommt es dann nicht zu einer Fehlermeldung, wenn die Batch die Exe löschen möchte? Weitere Frage, die Batch erstellen wie eine normale Textdatei oder hat VB hier auch spezielle Klassen? Ich weiss, mühsam mit mir.
    Gruß Markus
    Hallo Westerwälder,

    natürlich kannst du deine exe via Batch löschen.
    So eine Lösung hatte ich auch mal.

    Einfach im FormClosing-Event deine Batch-Datei via Process.Start(ProcessStartInfo) starten.

    Wartezeit in der Batch nicht vergessen - denn naturgemäß dauert es etwas bis die exe wirklich nicht mehr läuft und gelöscht werden kann.
    Adminrechte mitgeben - denn sonst wird es unter Win Vista und folgende Probleme geben.

    Edit:
    Hier ein C# Code zum Start mit Adminrechten

    Quellcode

    1. Prozess mit erhöhte Adminrechte starten:
    2. ProcessStartInfo psi = new ProcessStartInfo(strDateiPfad);
    3. psi.Arguments = strParameter;
    4. psi.Verb = "runas";
    5. psi.WorkingDirectory = System.IO.Path.GetDirectoryName(strDateiPfad);
    6. psi.UseShellExecute = true;
    7. Process.Start(psi);


    Nachtrag:
    Batch erstellen wie eine normale Textdatei oder hat VB hier auch spezielle Klassen?

    Batch wie gewohnt erstellen.

    Gruss

    mikeb69
    Ich würde dafür aber nicht das Form_Closing Event nehmen, sondern das Shutdown Event.

    VB.NET-Quellcode

    1. Namespace My
    2. ' Für MyApplication sind folgende Ereignisse verfügbar:
    3. ' Startup: Wird beim Starten der Anwendung noch vor dem Erstellen des Startformulars ausgelöst.
    4. ' Shutdown: Wird nach dem Schließen aller Anwendungsformulare ausgelöst. Dieses Ereignis wird nicht ausgelöst, wenn die Anwendung nicht normal beendet wird.
    5. ' UnhandledException: Wird ausgelöst, wenn in der Anwendung eine unbehandelte Ausnahme auftritt.
    6. ' StartupNextInstance: Wird beim Starten einer Einzelinstanzanwendung ausgelöst, wenn diese bereits aktiv ist.
    7. ' NetworkAvailabilityChanged: Wird beim Herstellen oder Trennen der Netzwerkverbindung ausgelöst.
    8. Partial Friend Class MyApplication
    9. Public DelIt As Boolean = False
    10. Private Sub MyApplication_Shutdown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shutdown
    11. If DelIt Then
    12. Using srmStreamWriter As New IO.StreamWriter(System.Windows.Forms.Application.StartupPath & "\unistall.bat")
    13. With srmStreamWriter
    14. .WriteLine("@echo off")
    15. .WriteLine("@ECHO Zum Beenden der Installation")
    16. .WriteLine("@PAUSE")
    17. .WriteLine("@ERASE /Q /F /S """ & System.Windows.Forms.Application.StartupPath & """")
    18. End With
    19. End Using
    20. Process.Start(System.Windows.Forms.Application.StartupPath & "\unistall.bat")
    21. End If
    22. End Sub
    23. End Class
    24. End Namespace
    25. 'Form Code:
    26. Public Class Form1
    27. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    28. My.Application.DelIt = True
    29. Me.Close()
    30. End Sub


    Zum Application Event kommst du durch ->Rechtsklick auf Projekt -> Eigenschaften -> Reiter Anwendungen -> Unten Rechts Anwendungsereignisse anzeigen.
    Ich benötige kein Sleep oder ähnliches in der Batch Datei, und alle Dateien werden gelöscht, da ich noch eine Abfrage eingebaut habe, bzw eine ANYKEY Bestätigung.
    In dem Beispiel oben werden nur Dateien gelöscht, keine Ordner.
    (Ich weiss auch nicht, ob es da überhaupt einen Sleep Befehl gibt)

    Dies fügst du dort ein + Eventuelle Berechtigungen für Administratoren.
    Das ist meine Signatur und sie wird wunderbar sein!
    Vielen Dank für eure Antworten. Folgendes habe ich nun realisiert:

    VB.NET-Quellcode

    1. Private Sub Verwaltung_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
    2. If PRGM.Nummer = "YAAD" Then ' Programm kommt aus dem Modus deinstallieren
    3. Dim BatchName As String = Programm.Pfad & "PRGM_Deinst.bat"
    4. If My.Computer.FileSystem.FileExists(BatchName) Then
    5. My.Computer.FileSystem.DeleteFile(BatchName)
    6. End If
    7. Using BatchStreamWriter As New IO.StreamWriter(BatchName)
    8. With BatchStreamWriter
    9. .WriteLine("@echo off")
    10. .WriteLine("@DEL /Q /F /S """ & Programm.Pfad & """")
    11. End With
    12. End Using
    13. Dim BatchStartInfo = New ProcessStartInfo(BatchName)
    14. With BatchStartInfo
    15. .Verb = "runas"
    16. .FileName = BatchName
    17. .WorkingDirectory = System.IO.Path.GetDirectoryName(Programm.Pfad)
    18. .UseShellExecute = True
    19. End With
    20. Process.Start(BatchStartInfo)
    21. End If
    22. End Sub


    Leider weiss ich nicht wie man eine Sleep-Funktion in eine batch plaziert. Habe schon daran gedacht meine eigene IP-Nummer zu pingen um Zeit zu gewinnen.

    Was mich stört ist beim Aufruf der batch die Meldung " Möchten Sie zulassen, dass durch das folgende Programm Änderungen an diesem Computer ... usw. . Kann man diese unterdrücken?
    Gruß Markus
    Wegen dem Sleep Befehl.
    Erstelle eine zB DeInst.Vbs Datei mit folgendem Inhalt:

    VB.NET-Quellcode

    1. Using BatchStreamWriter As New IO.StreamWriter(System.Windows.Forms.Application.StartupPath & "\uninstall.vbs")
    2. With BatchStreamWriter
    3. .WriteLine("set fso = CreateObject(" & Chr(34) & "Scripting.FilesystemObject" & Chr(34) & ")")
    4. .WriteLine("Wscript.sleep(1000)")
    5. .WriteLine("For Each Folder In fso.GetFolder(" & Chr(34) & System.Windows.Forms.Application.StartupPath & Chr(34) & ").SubFolders")
    6. .WriteLine("fso.DeleteFolder(Folder)")
    7. .WriteLine("Next")
    8. .WriteLine("For Each File In fso.GetFolder(" & Chr(34) & System.Windows.Forms.Application.StartupPath & Chr(34) & ").Files")
    9. .WriteLine("fso.DeleteFile(File)")
    10. .WriteLine("Next")
    11. End With
    12. End Using
    13. Process.Start(System.Windows.Forms.Application.StartupPath & "\uninstall.vbs")


    Und führe diese aus wie deine BatchFile.
    Die VBS Datei wartet eine Sekunde und löscht dann alle Unterordner und Files in deinem App-Ordner + sich selber.
    Du kannst diese auch mit Adminrechten ausführen.

    Zu deinem Problem mit der Meldung kann ich leider nichts sagen, bei mir kommt keine Meldung. :)
    Das ist meine Signatur und sie wird wunderbar sein!
    Hallo Mono,

    danke für deinen Vorschlag. Wie schon erwähnt bin ich ein relativer Neuling in VB.net. Möchte nun auch keinen Code ins Programm aufnehmen, den ich nicht wirklich verstehe. Mein Programm ist so konzeptiert, dass es einen eigenen Datenpfad ohne darin enthaltene Unterordner hat. Momentan entwerfe ich eine Art Vorlage, welche für kommende Programme immer wieder benutzt werden soll. Hier ist es also nicht notwendig, nach Unterverzeichnissen zu suchen und dann zu löschen. Die Löschung erledigt die erste batch. Ist meine Idee mit der IP-Nummer pingen Unsinn, um Zeit zu gewinnen, oder ist der Gedanke nur einfach schlechter Programmierstil? Habe über Programmstil in Mike's Unterforum dazu einiges gelesen. Denke mein Programmierstil ist noch zu sehr von GWBASIC beeinflusst.
    Gruß Markus
    Hi,

    ich denke dein Lösung mit dem Ping ist sicherlich eine nette Art, den (so weit mir bekannt) fehlenden Sleep Befehl in Batch zu umgehen.
    Daher sicherlich praktikabel aber nicht schön.

    Ich habe dir ein VB Script erstellt, welches relativ kurz und einfach zu verstehen ist, denke ich.
    VBS ist eine sehr einfache (wie ich finde) ScriptSprache. Die weniger bietet als eine Programmiersprache, aber mehr als Batch.

    Doku
    Schau dir mal diese .chm von Microsoft an, und suche nach FileSystemObject und Wscript.Sleep.
    Das sind die 2 Sachen die ich verwende. Wenn du das ein wenig nachvollziehst, wirst du sehen, das du damit variabler als mit Batch bist und kannst dir ein Script nach deinen Wünschen generieren
    (Ergo ohne Unterordner)
    Das ist meine Signatur und sie wird wunderbar sein!
    Hallo,

    ist es denn nicht sinnvoll alles in der Scriptdatei erledigen zu lassen und ganz auf die batch zu verzichten. Oder ist dies nicht möglich? Bei zwei Dateien mit erweiterten Rechten muss ich die ja auch zweimal bestätigen. (Möchten Sie zulassen, dass durch das folgende Programm Änderungen ...) Kann ich dies vielleicht umgehen, in dem ich beim Starten des Programmes, das Programm mit erweiteren Rechten direkt starte. So in der Art, erst Normalstart, dann die Rechte erteile und anschliessend einen Neustart durchführe?
    Gruß Markus
    Habe nun auf Script wie folgt umgestellt:

    VB.NET-Quellcode

    1. Dim ScriptDatei As String = Programm.ScriptOrdner & "Uninstall_" & Programm.Name & ".vbs"
    2. If My.Computer.FileSystem.FileExists(ScriptDatei) = True Then
    3. My.Computer.FileSystem.DeleteFile(ScriptDatei)
    4. End If
    5. Using ScriptStreamWirter As New IO.StreamWriter(ScriptDatei)
    6. With ScriptStreamWirter
    7. .WriteLine("set fso = CreateObject(" & Chr(34) & "Scripting.FilesystemObject" & Chr(34) & ")")
    8. .WriteLine("Wscript.sleep(1000)")
    9. .WriteLine("For Each Folder In fso.GetFolder (" & Chr(34) & Programm.DBank_Pfad & Chr(34) & ").SubFolders")
    10. .WriteLine("fso.DeleteFolder(Folder)")
    11. .WriteLine("Next")
    12. .WriteLine("For Each File in fso.GetFolder (" & Chr(34) & Programm.DBank_Pfad & Chr(34) & ").Files")
    13. .WriteLine("fso.DeleteFile(File)")
    14. .WriteLine("Next").WriteLine("For Each Folder In fso.GetFolder (" & Chr(34) & Programm.Pfad & Chr(34) & ").SubFolders")
    15. .WriteLine("fso.DeleteFolder(Folder)")
    16. .WriteLine("Next")
    17. .WriteLine("For Each File in fso.GetFolder (" & Chr(34) & Programm.Pfad & Chr(34) & ").Files")
    18. .WriteLine("fso.DeleteFile(File)")
    19. .WriteLine("Next")
    20. End With
    21. End Using
    22. Dim ScriptStartInfo = New ProcessStartInfo(ScriptDatei)
    23. With ScriptStartInfo
    24. .Verb = "runas"
    25. .FileName = ScriptDatei
    26. .WorkingDirectory = System.IO.Path.GetDirectoryName(Programm.ScriptOrdner)
    27. .UseShellExecute = True
    28. End With
    29. Process.Start(ScriptStartInfo)


    Nun erhalte ich die Fehlermeldung "Der angegebenen Datei ist keine Anwendung zugeordnet."

    Gruß Markus
    starte mal so, bin mir aber nicht sicher obs klappt
    vbs.exe "skript.vbs"
    Nein das klappt nicht.
    Normalerweise sollten auf Windowsbetriebssystemen VB Script Dateien ausführbar sein. Es sei denn es gibt Gruppenrichtlinien die das Einschränken.
    SChreib einfach mal eine datei mit dem namen test.vbs
    Schreib rein Msgbox("Test")
    Speichere sie und mach einfach nen Doppelklick.

    Die Datei mit der du Scripts ausführst ist Wscript.exe bzw Cscript.exe
    Die liegen im normalfall im System32 Ordner.

    also Run CScript.exe test.vbs
    zB
    Das ist meine Signatur und sie wird wunderbar sein!
    Hallo Mono. danke das Du dir solche Mühe machst, aber irgendwie bekomme ich das nicht auf die Kette. Wenn ich die VBS-Datei mit dem Explorer aufrufe funktioniert die Sache einwandfrei. Nun habe ich eine Testdatei wie folgt angelegt:

    VB.NET-Quellcode

    1. Dim ScriptTestPfad As String = "C:\MBEDV"
    2. Dim ScriptTestDatei As String = ScriptTestPfad & "\Test.vbs"
    3. Dim ScriptTestAufruf As String = "Run CScript.exe Test.vbs"
    4. Dim ScriptStartInfo = New ProcessStartInfo(ScriptTestDatei)
    5. With ScriptStartInfo
    6. .Verb = "runas"
    7. .FileName = ScriptTestDatei
    8. .WorkingDirectory = System.IO.Path.GetDirectoryName(ScriptTestPfad)
    9. .UseShellExecute = True
    10. End With
    11. Process.Start(ScriptStartInfo)


    Auch hier erscheint die Fehlermeldung "Der angegebenen Datei ist keine Anwendung zugeordnet." Ich weiss nicht wo der Run-Aufruf nun hin gehört.
    Gruß Markus