'v3.6*****************************************************
' File: Datei-Verzeichnis-Liste.vbs
' Autor: dieseyer@gmx.de
' dieseyer.de
'
' Listet alle Dateien und danach alle Verzeichnisse
' in einem / dem aktuellen Verzeichnis
' Zieht man ein Verzeichnis oder eine Datei auf das Skript
' werden zu diesem Verzeichnis die Info's angezeigt.
'*********************************************************
Vergl. Option Explicit
Option Explicit
Auf Grund von 'Option Explicit' müssen alle Variable definiert werden:
Dim WSHShell, fso, oArgs
Dim oFolders, oSubFolder, oFiles, Folder
Dim i, Text, Pfad, DateiX, VerzX, Verz(), Datei()
Zur Vereinfachung des Zugriffs auf Objekte werden mit Set =
einigen Variablen Verweise auf Objekte zugeweisen: Objektverweise.
Für ein Popup bedeutet das statt
WScript.CreateObject("WScript.Shell").Popup "Meldung"
nach dem Objektverweis durch die Variable 'WS'
Set WS = WScript.CreateObject("WScript.Shell")
nur noch:
WS.Popup "Meldung"
Da sich WS beim Lesen des Skripts nicht immer ohne weiteres zuordnen läßt,
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
Als erstes wird untersucht, ob dem Skript Parameter übergeben wurden bzw. ob
der Parameter-Zähler (oder Argumente-Counter) größer null ist.
Der Zähler 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?
War 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.
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!
Um eine 'vernünftige' Anzeige für das Skript zu garantieren, erhält Pfad als 'Notlösung' das Verzeichnis, in dem sich das Skript befindet:
Pfad = fso.GetFolder( "." ) ' Verzeichnis, in dem sich das Skript befindet
Damit ist der Bereich, der mit der obige Abfrage
If oArgs.Count > 0 Then
begonnen wurde, beendet:
End If
FileSystemObject
Jetzt soll überprüft werden, ob der an die Prozedur übergebene Parameter
auf eine Datei oder ein Verzeichnis verweist. Für Operationen mit Zugriffe
auf das Dateisystem wurde am Skriptanfang ein Objektverweis der Variable
fso zugewiesen:
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
Die Methode FileExists des FileSystemObject (fso.FileExists() ) 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 befindet, enthalten:
Pfad = fso.GetParentFolderName( Pfad )
Da nach dem If ... Then nur eine Anweisung folgen soll, kann alles
in eine Zeile geschrieben werden (und das End If entfällt):
if fso.FileExists( Pfad ) then Pfad = fso.GetParentFolderName( Pfad )
' obige Zeile wird nur ausgeführt, wenn "Pfad" eine Datei ist
Sollte Pfad kein Verzeichnis enthalten, wird das Skript nach einer (Fehler-) Meldung beendet.
if not fso.FolderExists( Pfad ) then
MsgBox UCase(Pfad) & " existiert nicht!" & vbCRLF & vbCRLF & " . . . das ist das Ende.", , WScript.ScriptName
WScript.Quit
End If
FileSystemObject
Zunächst sollen alle Dateien im Verzeichnis Pfad ermittelt
werden. Es ist also eine (Files-) Methode von einem
(Verweis auf ein) Verzeichnis erforderlich, die alle Dateien dieses
Verzeichnisses ermitteln kann. 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.
' Dateiliste an Array übergeben
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
i = 0
Set oFolders = fso.GetFolder( Pfad )
Set oFiles = oFolders.Files
Da oFolders nur einmal verwendet wird (um die Files -Methode
bereit zu stellen), läßt sich auch
Set oFiles = fso.GetFolder( Pfad ).Files
statt
Set oFolders = fso.GetFolder( Pfad )
Set oFiles = oFolders.Files
schreiben.
FileSystemObject
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 Datei(i) ) übergeben werden, um sie innerhalb der
For ... Next -Schleife auszuwerten. Von jedem DateiX -Objekt
sind über Methoden
(Vergl. fso-Beispielcode.html bzw. fso-Beispielcode.vbs)
verschiedene Eigenschaften abrufbar. Hier ermittelt die Methode Name
(DateiX.Name) den Dateinamen (mit komplettem Pfad: DateiX.Path),
der Datei(i) zugewiesen wird.
For Each DateiX In oFiles
Array
Jeder ermittelte Dateiname soll in einer Variable gespeichert werden.
Da beim Skriptaufruf nicht bekannt ist, wie viele Dateien sich in einem
Verzeichnis befinden, läßt sich auch nicht jede mögliche Variable deklarieren
(Dim -Anweisung am Skriptanfang; D1, D2, ..).
Als Alternative bietet sich die Verwendung eines Arrays an. Nach dem die
Array-Variable Datei( ) am Skriptanfang deklariert wurde,
steht ein Datenfeld mit der Länge null bereit. Eine ReDim
-Anweisung verkleinert oder vergrößert die Dimensionen des Arrays.
Mit der Anweisung i = 0 wurde der Zähler, der die Anzahl
der Datei (-namen) zählt, auf null gesetzt. Der erste Durchlauf der
For ... Next -Schleife führt ein ReDim Preserve
Datei(0) aus (was man sich also hätte sparen können). Nachdem
die Variable Datei(0) ihren Wert erhalten hat, wird
i um eins hoch gezählt: i = i + 1. Wenn es eine
weitere Datei gibt - das stellt die Anweisung
For Each DateiX In oFiles fest - erfolgt ein
ReDim Preserve Datei(1), bevor Datei(1) ihren
neuen Wert erhält.
ReDim Preserve Datei(i)
Datei(i) = DateiX.Name
i = i + 1
Die Schleife wird so oft bis Next durchlaufen, bis For Each DateiX In oFiles das Ende fest stellt und die Schleife beendet:
Next
Zwei Objektverweise werden nicht mehr gebraucht und sind deshalb zu nichts mehr zu gebrauchen:
Set oFiles = nothing
Set oFolders = nothing
Sollte die For Each DateiX In oFiles nicht mindestens einmal durchlaufen worden sein, befindet sich keine Datei im getesteten Verzeichnis; es ist also i = 0 .
' Array an Text übergeben
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Text = ""
If i > 0 then ' wenn es Datei(en) gibt
Array
Gibt es im getesteten Verzeichnis also mindestens eine Datei, wird
die folgenden For .. Next - Schleife so lange
durchlaufen, bis das obere Ende (UperBond; UBound) des Arrays
Datei() erreicht ist.
For i = 0 to UBound( Datei )
Zeichenketten
Für eine Anzeige der Dateiliste werden die einzelnen Dateinamen
mit vorangestellter Pfadangabe an die Variable Text übergeben.
Um den Text nicht als fortlaufenden Text zu speichern, fügt
& vbCRLF
einen Zeilenumbruch (entspricht einem 'Enter') ein.
Hätte man weiter oben
Datei(i) = DateiX.Path
statt
Datei(i) = DateiX.Name
geschrieben, würde jetzt
Text = Text & Datei(i) & vbCRLF
reichen, weil in Datei(i) der Dateiname mit kompletter
Pfadangabe bereits hinterlegt worden wäre.
Text = Text & Pfad & "\" & Datei(i) & vbCRLF
Die Schleife wird so oft bis Next durchlaufen, bis UBound( Datei ) erreicht ist:
Next
Sollte der obige Test auf i > 0 erfolglos (negativ) gewesen sein, geht es hier bei Else weiter und Text erhält eine 'vernünftige' Zeichenkette.
Else
Text = "keine Dateien vorhanden."
Damit hat Text nach der Abfrage If i > 0 then für eine positive oder negative Antwort einen Inhalt. Das If ..Then ..Else ist zu Ende:
End If
Zur Anzeige der in Text gesammelten Informationen werden eine Überschrift und zwei vbCRLF voraus geschickt. Enthält Text sehr viele Informationen, kann es vorkommen, dass von MsgBox nicht alle Zeilen (nur ca. die ersten 1.000 Zeichen) angezeigt werden:
MsgBox UCase(Pfad) & " enthält folgende Dateien:" & vbCRLF & vbCRLF & Text, , WScript.Scriptname
Ein guter Beobachter stellt jetzt sicher fest, dass sich das ganze
(Verzeichnisliste statt Dateiliste in grobem Zügen) noch einmal wiederholt.
Wer das nicht erkennt, hat das bisher ausgeführte wohl nicht verstanden
und würde weitere Erklärungen sicher auch versickern lassen.
Jeder andere Leser wird sich den Rest des Skripts als Übung sicher
selbst erarbeiten wollen und erwarten, dass ich hier aufhöre.
. . . nichts lieber als das!
' Verzeichnisliste an Array übergeben
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
i = 0
Set oFolders = fso.GetFolder( Pfad )
Set oSubFolder = oFolders.SubFolders
For Each VerzX In oSubFolder
ReDim Preserve Verz(i)
Verz(i) = VerzX.Name
i = i + 1
Next
Set oFiles = nothing
Set oFolders = nothing
' Array an Text übergeben
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Text = ""
If i > 0 then ' wenn es Verzeichnis(se) gibt
For i = 0 to UBound( Verz )
Text = Text & Pfad & "\" & Verz(i) & vbCRLF
Next
Else
Text = "keine Unterverzeichnisse vorhanden."
End If
MsgBox UCase(Pfad) & " enthält folgende Verzeichnisse:" & vbCRLF & vbCRLF & Text, , WScript.Scriptname