Eigenes Programmverzeichnis löschen (neuer Versuch)

  • VB.NET

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von xChRoNiKx.

    Eigenes Programmverzeichnis löschen (neuer Versuch)

    Hallo zusammen,

    Mein erster Thread wurde leider geschlossen, aus Befürchtungen dass ich damit "Schlimmes" anstellen könnte.

    Hier noch zuerst kurz ein paar Erklärungen, für was ich das genau brauche (ich wurde gebeten, dies mitzuteilen)
    Ich arbeite an einer Software, wobei die ausführbare Datei gleichzeitig auch Installer- und Deinstaller ist. Dies aus Einfachheitsgründen, der User lädt nur eine Datei herunter und hat das gesamte Paket. Um das Programm zu Deinstallieren, klickt man über das Startmenü auf die Verknüpfung "Uninstall", welche dann die Exe mit einer Attribute aufruft und das Programm und die Verknüpfungen entfernt. Hier haperts aber noch etwas, siehe nachfolgend:


    Die soeben aufgerufene Exe-Datei lässt sich einfach über folgenden Code löschen, indem zuerst eine Konsole aufgerufen wird und diese dann zeitlich verzögert - hier 3 Sekunden - die Datei löscht (zum Zeitpunkt, wo sich das Programm selbst wieder geschlossen hat mit dem Befehl "END")

    Quellcode

    1. Dim loeschen As String = "cmd.exe /C choice /C Y /N /D Y /T 3 & Del " & Application.ExecutablePath
    2. Shell(loeschen, AppWinStyle.Hide)
    3. END



    Ich kann auch alle anderen Dateien und Unterverzeichnisse des Programmordners mittels nachfolgendem Code löschen:

    Quellcode

    1. 'Dim loeschen2 As String = "cmd.exe /C choice /C Y /N /D Y /T 3 & rmdir /S /Q " & IO.Directory.GetParent(Application.ExecutablePath).ToString
    2. 'Shell(loeschen2, AppWinStyle.Hide)
    3. 'END


    Dieser soeben beschriebene Code sollte jedoch auch das (danach) leere Verzeichnis löschen, tut es aber nicht. Dies gilt übrigens auch für das Startmenü-Verzeichnis, von wo aus man die Exe über die Verknüpfung aufgerufen hat. Man kann im Startmenü-Verzeichnis die Verknüpfungen entfernen, den leeren Ordner jedoch nicht.

    Es scheint, dass es trotz der Schliessung/Beendigung des Programms immer noch einen Hintergrundprozess offen hat, welches den Zugriff (das Löschen des leeren Ordners) verhindert. Ich könnte dies einfach so sein lassen, doch der Benutzer sieht dann den noch leeren Ordner im Startmenü und im Programmpfad und das ist unschön.

    Ich habe auch versucht, eine Batch Datei anstelle des CMD commands zu erstellen und dann aufzurufen. Sogar das Aufrufen einer solchen Batch-Datei und dann ein Aufrufen wieder einer Batch-Datei von der ersten Batch Datei aus hat nicht geholfen! Es geht natürlich, wenn die EXE geschlossen ist und die Batch Datei separat geöffnet wird (nicht über den Programmcode). Hat jemand einen Vorschlag, wie das (danach leere) Programmverzeichnis gelöscht werden könnte ohne dass man eine zweite EXE Datei hat, welche sich an einem anderen Ort befindet? Gibt es vielleicht einen speziellen END Befehl, welcher alle Ressourcen löscht und so auch den Zugriff auf das Verzeichnis selbst ermöglicht? Ich habe es auch mit Application.exit versucht aber dies half nicht.


    Danke für eure Antworten

    Manu234211 schrieb:

    aus Befürchtungen dass ich damit "Schlimmes" anstellen könnte.
    Lesen bildet.
    Nicht Du hast was Schlimmes vor, sondern eine Lösungen zu diesem Thema
    für illegale verschleierung von Schadsoftware verwendet werden könnte
    , also Leute, die Schlimmes tun wollen.
    Sorry.
    CloseRequest
    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).
    VB-Fragen über PN / Konversation werden ignoriert!
    Ich lasse den Thread jetzt mal offen, werde ihn aber gut beobachten.

    @Manu234211 - Wenn ein Moderator dir sagt das du etwas unterlassen sollst, sollte man dem in der Regel auch nachkommen.

    Hier an dieser Stelle möchte ich nun nochmals festhalten: Hierfür gibt es Installer. (WIX, InnoSetup uvm.)
    Du tust dir selbst keinen gefallen dies über dein eigenes Programm, Script oder ähnliches abzuwickeln. Installer machen das gut, und vorallem so das man das Programm dann auch in der Systemsteuerung wiederfindet. (Wie es sich gehört).
    Gerne sind wir die hier behilflich wenn du Unterstützung beim erstellen eines Installers benötigst, zu deinem Thema wird hier allerdings niemand (aus den genannten Gründen) Antworten.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Moin,

    ich habe auch manchmal das Problem das sich ein Ordner nicht löschen lässt(OT Hätte bei Win7 bleiben sollen bis zum Suppoertende, da hatte ich das nicht), es gibt mehrere Möglichkeiten warum ein Ordner gesperrt sein kann. einmal vom Filesystem selbst durch Rechte, durch Zugriffe von anderen Programmen, wie auch API funktionen(LockFile, LockFileEx), evtl. noch mehr.

    Solche sperren aufzuheben kann schwierig sein, es gibt möglichkeiten via API(KA welche Funktionen) zu erfahren wer an dem Ordner hängt, damit kann dann eine Lösung gebaut werden.

    Aber ich verstehe nicht wirklich warum eine MELT-Funktion nötig ist. Wenn was gelöscht werden muss kann es der User selbst tun.
    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    Solange es den Boardregeln nicht widerspricht gerne. Sollten hier sperrmechanissmen von Windows oder ähnliche "Hacks" auftauchen wird gelöscht.
    Dafür ist die Moderation im übrigem da.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    @Nofear23m
    Nö, da gibts keine Hacks oder die Umgehung von Sperrmechanismen. Einfach nur die für genau solche Fälle vorgesehenen Windows Mittel.

    @Manu234211
    Beschäftige Dich mal mit der Aufgabenplanung und verlagere das löschen der Reste nach dort. Dann kannst Du das nach der nächsten Anmeldung durchführen und diese Aufgabe sich selbst anschliessend selbst entfernen lassen. Alternativ gibts dann auch noch die Möglichkeit, das löschen der Reste beim nächsten Systemstart oder der nächsten Anmeldung an Windows über die Registryschlüssel "RunOnce" in LocalMachine bzw. in CurrentUser ausführen zu lassen. Anweisungen, die in "Runonce" liegen, werden nach ihrer Ausführung von Windows automatisch entfernt.

    Beide Möglichkeiten sind für genau solche Fälle vorgesehen und sollten vorrangig genutzt werden. Man muss das Rad nämlich gar nicht neu erfinden und beide Möglichkeiten decken sich mit Deiner Vorstellung, alles mit nur einer einzigen Programmdatei zu erledigen. Jede Deinstallationsroutine, die nach ihrer Ausführung Reste zu tilgen hat, die noch im Zugriff des Systems sind, geht genau so vor.
    Gruss Alex

    NoIde schrieb:

    Allein der gezeigte Code aus dem Eröffnungspost könnte schon missbraucht werden
    Das hat jetzt aber schon einen Anflug von Paranoia.
    Natürlich kann man mit RMDIR und DEL Verzeichnisse und Dateien löschen.
    Daraus generell böse Absicht abzuleiten, ist schon ein wenig weit hergeholt.
    Es gibt ja schliesslich auch noch die UAC, die sich dazwischen hängt, um heimliche Datenzerstörung zu unterbinden.

    Dass Deinstallationsaufgaben in einem Installer besser aufgehoben sind, steht außer Zweifel.
    Früher war das jedoch gang und gebe, dass sich ein Programm beim ersten Aufruf selbst installierte und die Deinstallationsroutine als Menüpunkt abrufbar war.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    petaod schrieb:

    Es gibt ja schliesslich auch noch die UAC, die sich dazwischen hängt, um heimliche Datenzerstörung zu unterbinden.


    Ja, bei ordner mit speziellen gesetzten rechten

    petaod schrieb:

    Daraus generell böse Absicht abzuleiten, ist schon ein wenig weit hergeholt.


    Nun ja, weit hergehohlt finde ich das nicht. Immerhin kann eine Anwendung so eine selbstlöschung "beauftragen". Man sieht ja das eine Zeitangabe von 3 Sekunden in den Argumenten ist, Shell gestartet, Programm beenden, Programm wird 3 Sekunden später gelöscht. Also die möglickeit des "Missbrauchs" ist vorhanden.
    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    @NoIde Demnach dürfte Crypto (Verschlüsselung) hier auch nicht besprochen werden, immerhin ist es Bestandteil von Ransomware.
    Können wir dann wieder zum Thema kommen??

    Danke
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    @petaod Du stärkst mir etwas den Rücken :) Ich hätte nicht gedacht, so eine Diskussion darüber auszulösen.

    @areiland Vielen Dank dafür, endlich ein Lösungsvorschlag. Gemäss deiner Lösung soll also nach Beendigung der Prozedur informiert werden, dass ein Systemstart nötig ist (so wie ich das noch von alten Programmen her kenne). Ich werde mir dein Vorschlag anschauen, kenne mich hier noch nicht so gut aus.

    Mein Programm ist auch portabel, dass heisst eine Installation ist nicht zwingend. Deshalb will ich kein separater Installer. Es soll nur ein besseres Benutzererlebnis geschaffen werden und die Möglichkeit geboten werden, Verknüpfungen, Programmordner etc. nach der Registrierung zu erstellen.

    Melde mich nochmals mit der abschliessenden Lösung, wenn es keine weiteren Lösungsvorschläge geben sollte!
    @Manu234211
    Ja, Du trägst z.B. in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce den Befehl zum Löschen des Programmordners und einen weiteren zum Löschen der erstellten Ordner und Verknüpfungen im Startmenüordner ein. Dann lässt Du das Executable sich selbst löschen und zeigst mit MessageBox.Show eine Messagebox an, die darauf hinweist dass das entfernen der Programmordner und der Startmenüeinträge erst beim folgenden Neustart erfolgen werden.

    Wobei ich dazu allerdings auch sagen muss, dass mein Verständnis eines portablen Programmes es aussschliesst, dass dieses Programm einen Programmordner und Startmenüeinträge erstellt. Portabel bedeutet für mich, dass ich das Programm irgendwohin kopiere, allenfalls noch entpacke, es dann einfach starte und es tut was es soll. Ohne auf dem System noch Ordner zu erstellen oder Startmenüeinträge zu hinterlegen.
    Gruss Alex
    @areiland
    Danke, ich glaube das ist die Lösung. Ich werde mich in das Thema einlesen und mich nochmals melden.

    Ich gebe Dir recht, die Software ist natürlich auch nur insofern portabel, als dass man sie nur auf Systemen verwenden kann, für welche der Registrierungsschlüssel aktiv ist. Es wird dem Benutzer die Wahl gelassen, für die Datei beim ersten Öffnen noch einen Ort und Verknüpfungen anzulegen oder das Programm sofort zu starten und ggf. selbst das Programm an einen bestimmten Ort zu kopieren. Der erfahrene User wird Letzteres bevorzugen. Dann werden natürlich Registry Einträge und der Schlüssel beim Löschen nicht entfernt.

    Neu

    Hier nochmals zum Thema abschliessend ein paar Anmerkungen, nach einiger Testerei. Der Vorschlag von @areiland funktioniert grundsätzlich und ich wende dies nun an.

    - Abmelden genügt, Neustart nicht erforderlich
    - es öffnet sich kein Konsolenfenster und Windows warnt auch nicht davor (ich hätte gedacht, bei Löschvorgängen würde Windows womöglich nochmals rückfragen)
    - funktioniert auch für leere Ordner (ohne Dateien/Unterordner) und der Pfad kann beliebig sein (z.B. im Windows-Programmverzeichnis oder Startmenü)
    - wenn der Zielordner/Zieldatei nicht mehr existiert, kommt keine Fehlermeldung und der RunOnce-Eintrag ist trotzdem dann weg

    Jedoch:
    - wenn man als Benutzer ohne Admin-Rechte bei Windows angemeldet ist, kann man unter Einbezug von Admin-Rechten trotzdem in die Registry schreiben (für mich kein Problem, denn mein Programm setzt Admin-Rechte voraus), der RunOnce wird jedoch bei der Neuanmeldung als Non-Admin nicht ausgeführt bzw. es werden bei der Neuanmeldung keine Ordner gelöscht (dies gilt für beides LocalMachine und auch für CurrentUser).

    Ich habe auch versucht, die EXE (welche automatisch mit Admin-Rechten gestartet wird) quasi als Autostart zu starten und dies so zu umgehen. Jedoch starten EXE Dateien nur wenn sie Admin-Rechte nicht voraussetzen wie ich festgestellt habe. Ich muss deshalb den User darauf hinweisen, er solle sich beim Neustart als Admin anmelden ansonsten erfolgt keine Entfernung der Reste des Programms (ausser jemand hat hier noch einen anderen Vorschlag?)

    Neu

    Ich habe noch nie soviel umständliche Arbeit gesehen um ein Programm zu löschen.

    bei portable Programmen schon gar nicht die löscht der user selber.

    bei zu installierenden Programmen gibt es wenn richtig installiert bei windows die programm liste um das ganze zu deinstallieren.

    Also warum nicht normale Methoden verwenden statt dem user dann noch zu sagen melde dich mal als admin an.
    Grüße , xChRoNiKx

    Nützliche Links:
    Visual Studio Empfohlene Einstellungen | Try-Catch heißes Eisen