http://dieseyer.de • all rights reserved • © 2003 v3.6

'v3.6*****************************************************
' File: deltree.vbs
' Autor: dieseyer@gmx.de
' dieseyer.de
'
' Löscht alle Dateien und danach alle Verzeichnisse in
' einem Verzeichnis.
'
' Zieht man ein Verzeichnis auf das Skript, werden alle
' enthaltene Dateien und Unterverzeichnisse gelöscht.
' Zieht man eine Datei auf das Skript, wird das Verzeich-
' nis, in dem sich die Datei befindet, ermittelt und wie
' beschrieben gelöscht.
'*********************************************************

Vergl. Option Explicit Option Explicit

Auf Grund von 'Option Explicit' müssen alle Variable definiert werden: Dim WSHShell, fso, oArgs
Dim i, Text, Pfad

Zur Vereinfachung des Zugriffs auf Objekte werden mit Set = einigen Variablen Ver- weise auf Objekte zugeweisen: Objektverweise. Für ein Popup bedeutet das statt WScript.CreateObject("WScript.Shell").Popup "Meldung" nach dem Objektverweis auf die Variable 'WS' Set WS = WScript.CreateObject("WScript.Shell") nur noch: WS.Popup "Meldung" Da WS auch auf WScript verweisen könnte, verwende ich WSHShell; andere Programmierer nehmen lieber oWSHShell als Variable. Set WSHShell = WScript.CreateObject("WScript.Shell")
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
set oArgs = Wscript.Arguments

Jetzt wird untersucht, ob dem Skript Parameter übergeben wurden, ob der Parameter- Zähler also größer null ist. Der Zähler bzw. Counter steht auf dem Stand, den der nächste Parameter erhalten würde: auf den ersten Parameter wartet der Zähler mit Zählerstand null; ist der erste Parameter 'angekommen' wartet der Zähler mit dem Zählerstand eins auf den nächsten Parameter und bleibt auf eins stehen, wenn kein weiterer Parameter übergeben wird. If oArgs.Count > 0 Then ' gibt es Argumente?

Ist die Anzahl der Parameter größer null, dürfte der erste Parameter ein Verzeichnis oder eine Datei enthalten und wird an die Variable Pfad übergeben. Die Überprüfung, ob es wirklich ein Verzeichnis oder eine Datei ist, erfolgt später. Pfad = oArgs.item(0) ' erstes Argument

Ist die obige Abfrage If oArgs.Count > 0 Then nicht 'positiv' beantwortet worden, geht der Programmablauf hier weiter: Else ' es gibt keine Argumente!

Da der Nutzer des Skripts offensichtlich nicht weiss, wie es zu benutzen ist (sonst hätte er ihm ja einen Parameter mit gegeben), wird im folgenden ein erklärender Text zu- sammen gebaut. Um in der Variablen Text nicht nur fortlaufenden Text zu speichern, sind durch & vbCRLF & vbCRLF (hier zwei) Zeilenumbrüche (entspricht einem / zwei 'Enter') eingefügt. Text = ""
Text = Text & "Das ganze funktioniert so:" & vbCRLF & vbCRLF
Text = Text & "Ein Verzeichnis auf das Skript ziehen & fallen lassen" & vbCRLF
Text = Text & ". . . und es wird gelöscht." & vbCRLF & vbCRLF
Text = Text & "Eine Datei auf das Skript ziehen & fallen lassen" & vbCRLF
Text = Text & ". . . und das Verzeichnis, in dem sich die Datei befindet wird gelöscht." & vbCRLF & vbCRLF
Text = Text & "ACHTUNG: Der Papierkorb bleibt leer!!!"

Zur Anzeige der in Text gespeicherten Zeichenfolge (String) habe ich hier die .Popup- Methode verwendet. Durch die Zahl 30 ist fest gelegt, dass die Meldung nach 30 sec einfach von selbst verschwindet. Nach der 30 folgt eine Methode, die den Namen des Skriptes liefert, das gerade läuft. Dadurch steht im oberen blauen Balken der Meldung der Skriptname; man sieht also, welches Skript diese Meldung 'verursacht' hat. Die anschließende 64 'zaubert' noch ein Bildchen mit einem ' i ' in das Popup und weisst somit darauf hin, dass dies nur eine Information ist. WSHShell.Popup Text , 30, WScript.ScriptName, 64 + 0

Da wir hier in dem Bereich des Skripts sind, der eine Fehlerbehandlung (nämlich eines Bedienfehlers) vor nimmt, soll die Skriptabarbeitung jetzt aufhöhren: WScript.Quit

Damit ist der Bereich, der mit der obige Abfrage If oArgs.Count > 0 Then begonnen wurde, beendet: End If

Da in der Variable Pfad 'irgend etwas' steht kann, erfolgt jetzt die Prüfung, ob dieses 'irgend etwas' etwas mit dem Dateisystem zu tun hat. Oben wurde mit Set fso = WScript.CreateObject("Scripting.FileSystemObject") der Variable fso ein Objektverweis auf das FileSystemObject (des Windows Scripting) zugewiesen. Um zu testen, ob die Variable Pfad eine Verzeichnis oder eine Datei ent- hält, benutzen wir nun die FolderExists-Methode des FileSystemObjects. Die Prüfung auf einen Ordner genügt, da in einem Dateinamen fast immer auch ein Verzeichnis enthalten ist. Nur wenn das Abfrageergebnis nicht positiv ausfällt, wird dieser Fehler kurz gemeldet und das Skript beendet. Enthält bei einer Datei der Dateiname kein Verzeichnis, muss die Datei aus dem Hauptverzeichnis (z.B. c:\tmp.txt) stammen - auch dann erfolgt eine Fehlermeldung: if not fso.FolderExists( Pfad ) then
WSHShell.Popup UCase(Pfad) & " entält kein Verzeichnis!" & vbCRLF & vbCRLF & " . . . das ist das Ende.", 30, WScript.ScriptName, 64 + 0
WScript.Quit
End If

Der wesentliche Rest des Skripts ist in zwei SUB-Prozeduren 'ausgegeliedert'. Dadurch kann man zum einen durch ein ' den Aufruf der SUB-Prozedur Sicherheitsabfrage ab- schalten und zum anderen kann man eine SUB-Prozedur (z.B. für Deltree "c:\temp" ein- facher in andere bzw. eigene Skripte übernehmen. Es gehört sich dann aber auch, den Autor der Prozedur wohlwollend zu nennen. '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SicherheitsAbfrage Pfad ' Sub Aufruf
DelTree Pfad ' Sub Aufruf
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Sind die Prozeduren beendet, geht auch das Skript nach einer kleinen Meldung dem Ende entgegegn: WSHShell.Popup UCase(Pfad) & " ist jetzt leer!", 13, WScript.ScriptName, 64 + 0
WScript.Quit

Durch die Zeile DelTree Pfad ' Sub Aufruf wurde die SUB-Prozedur Deltree mit dem Parameter Pfad aufgerufen. Die nachfolgende Zeile Sub DelTree ( Pfad ) zeigt an, dass hier die SUB-Prozedur be- ginnt und der übergebene Parameter (in der SUB-Prozedur-Aufruf - Zeile) an die (Pro- zedur-) Variable Pfad zur Verwendung innerhalb der Prozedur übergeben wird. (Das die Variable Pfad auch ausserhalb der Prozedur, nämlich beim Aufruf der Prozedur, existiert und verwendet wird, ist nicht Bedingung. Man kann auch so vorgehen: Path = "c:\temp" DelTree Path DelTree "d:\tempo" Immer wird der Parameter aus dem Prozedur-Aufruf für die Variable Pfad innerhalb der Prozedur verwendet (Vergl. Sub- und Function-Prozeduren - eine Einführung). '*********************************************************
Sub DelTree ( Pfad )
'*********************************************************

Mit den folgenden Dim - Anweisungen werden Variablen für den (Prozedur-) internen Gebrauch festgelegt. Sollten diese Variablen (-namen) auch außerhalb der Prozedur verwendet werden, bleibt deren Inhalt unberührt, selbst wenn innerhalb der Prozedur mit den Variablen gearbeitet wird. Dim fso, oFolders, oSubFolder, oFiles, WSHShell
Dim Text, DateiX, VerzX

Das gilt auch bei Variablen mit Objektverweisen: Set WSHShell = WScript.CreateObject("WScript.Shell")
Set fso = WScript.CreateObject("Scripting.FileSystemObject")

Jetzt soll endlich überprüft werden, ob der an die Prozedur übergebene Parameter auf eine Datei oder ein Verzeichnis verweist. Die Methode FileExists des fso. liefert ein positives Ergebnis, wenn ein Dateiname geprüft wird. Ist dies der Fall, soll Pfad nicht mehr einen Dateinamen sondern das Verzeichnis, in dem sich diese Datei be- findet, enthalten: Pfad = fso.GetParentFolderName( Pfad ) Da nach dem if ... then nur eine Anweisung folgt, kann (oder besser: muss) man sich das End If sparen: if fso.FileExists( Pfad ) then Pfad = fso.GetParentFolderName( Pfad )
' obige Zeile wird nur ausgeführt, wenn "Pfad" eine Datei ist

Damit die Löschoperation keine Dateien übergeht, die durch eingeschaltete Attribute 'System', 'Readonly' oder 'Hidden' vor dem Löschen (etwas) geschützt sind, müssen zuerst die Attribute gelöscht werden. Am schnellsten geht das mit dem 'attrib'-Befehl, der in einer DOS-Box (Vergl. MS-DOS- Eingabeaufforderung) läuft und durch den Parameter ' /S ' alle Unterverzeichnisse mit erfasst. (Eientlich kann man auch das Eingabeaufforderungs-DelTree statt dieser .VBS- Variante benutzen.) ' Datei-Attribute System, Readonly, Hidden zurück setzen
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Text = "%comspec% /c Attrib """ & Pfad & "\*.*"" /S -s -r -h "
WSHShell.run Text, 4, True

' Dateiliste
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Da im folgenden die Variable Text wieder neuen Text erhalten soll, wird sie geleert: Text = ""

Zunächst sollen alle Dateien im Verzeichnis Pfad ermittelt und gelöscht werden. Es ist also eine (Files-) Methode von einem (Verweis auf ein) Verzeichnis erforderlich, die alle Dateien dieses Verzeichnisses ermittelt. Mit Set oFolders = fso.GetFolder( Pfad ) verweist oFolders auf das durch Pfad genannte Verzeichnis. Und mit Set oFiles = oFolders.Files verweist oFiles auf die Files -Methode der oFolders -Methode des fso-Objekts. Set oFolders = fso.GetFolder( Pfad )
Set oFiles = oFolders.Files Da oFolders nur einmal verwendet wird (um die Methode .Files bereit zu stellen), kann man auch Set oFiles = fso.GetFolder( Pfad ).Files statt Set oFolders = fso.GetFolder( Pfad ) Set oFiles = oFolders.Files schreiben.
Die For ... Next -Schleife wird für jede (each) XxXxX so lange durchlaufen, bis alle XxXxX (Dateien) in oFiles einmal angesprochen wurden. Dieses XxXxX (Datei-Objekt bzw. der Verweis auf eine Datei) muss an eine Variable (hier DateiX) übergeben wer- den, um sie innerhalb der For ... Next -Schleife auszuwerten. Von jedem DateiX-Ob- jekt sind über Methoden (Vergl. fso-Beispielcode.html bzw. fso-Beispielcode.vbs) ver- schiedene Eigenschaften abrufbar. Hier ermittelt die Methode .Path (DateiX.Path) den Dateinamen mit komplettem Pfad, der in Text (zusammen mit dem bishherigen In- halt) gesammelt wird. For Each DateiX In oFiles
Text = Text & DateiX.Path & vbCRLF

Die anschließende Zeile hat nichts besseres zu tun, als die gerade ermittelte Datei zu löschen: fso.DeleteFile DateiX.Path, True ' True: Löschen erzwingen
Next
Set oFiles = nothing
Set oFolders = nothing

Sollte die Variable Text immer noch leer sein, wie vor der For ... Next -Schleife mit mit Text = "" angewiesen, war die ganze Schleife zur Suche nach Dateien sinnlos: es ist ein leeres Verzeichnis (enthält zumindest keine Dateien): If Text = "" then Text = "keine Dateien vorhanden."

Das Ergebnis der Suche nach zu löschenden Dateien wird (für 3 sec) angezeigt: WSHShell.Popup "In " & UCase(Pfad) & " wurden folgende Dateien gelöscht:" & vbCRLF & vbCRLF & Text, 3, WScript.ScriptName, 64 + 0




' Verzeichnisliste
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Da hier nichts wirklich Neues kommt, spare ich mir die Erklärung - selber denken macht klug. ;-) Text = ""
Set oFolders = fso.GetFolder( Pfad )
Set oSubFolder = oFolders.SubFolders
For Each VerzX In oSubFolder
Text = Text & VerzX.Path & vbCRLF
fso.DeleteFolder VerzX.Path, True ' True: Löschen erzwingen
Next
Set oFiles = nothing
Set oFolders = nothing

If Text = "" then Text = "keine Unterverzeichnisse vorhanden."

WSHShell.Popup "In " & UCase(Pfad) & " wurden folgende Verzeichnisse gelöscht:" & vbCRLF & vbCRLF & Text, 3, WScript.ScriptName, 64 + 0

Set WSHShell = nothing
Set fso = nothing

End Sub ' DelTree
'*********************************************************


'*********************************************************
Sub SicherheitsAbfrage( Pfad ) ' Anfang
'*********************************************************

Text = ""
Text = Text & "Es wird jetzt das Verzeichnis" & vbCRLF & vbCRLF
Text = Text & vbTAB & UCase( Pfad )
Text = Text & vbCRLF & vbCRLF & "unwiederbringlich gelöscht." & vbCRLF & vbCRLF
Text = Text & "ACHTUNG: Der Papierkorb bleibt leer!!!"

If not vbYes = WSHShell.Popup ( Text , 30, WScript.ScriptName, 48 + 4 + 256 ) then
WSHShell.Popup UCase(Pfad) & vbTab & vbCRLF & vbCRLF & vbTab & "wird nicht gelöscht!" & vbCRLF & vbCRLF & vbTab & " . . . das ist das Ende.", 30, WScript.ScriptName, 64 + 0
WScript.Quit
End if


Text = vbCRLF
Text = Text & "DIE LETZTE WANUNG!" & vbCRLF & vbCRLF
Text = Text & "Es wird jetzt das Verzeichnis" & vbCRLF & vbCRLF
Text = Text & vbTAB & UCase( Pfad )
Text = Text & vbCRLF & vbCRLF & "unwiederbringlich gelöscht." & vbCRLF & vbCRLF
Text = Text & "ACHTUNG: Der Papierkorb bleibt leer!!!"

If not vbOK = WSHShell.Popup ( Text , 30, WScript.ScriptName, 16 + 1 + 256 ) then
WSHShell.Popup UCase(Pfad) & vbTab & vbCRLF & vbCRLF & vbTab & "wird nicht gelöscht!" & vbCRLF & vbCRLF & vbTab & " . . . das ist das Ende.", 30, WScript.ScriptName, 64 + 0
WScript.Quit
End if
Text = ""

Set fso = nothing

End Sub ' SicherheitsAbfrage
'*********************************************************

http://dieseyer.de • all rights reserved • © 2003 v3.6