Unterthema: Sicher skripten
Unterthema: Schritt für Schritt
Unterthema: Mehr Funktionen mit DlgTools.ocx
Unterthema: WinZip per Befehlszeile steuern
Unterthema: Listing 1: Dir2Doc.vbs
Unterthema: Listing 2: DirInfo.vbs
Unterthema: Listing 3: FileBackup.vbs
Unterthema: Listing 4: MailPost.vbs
Unterthema: Listing 5: Mp3Play.vbs
Unterthema: Listing 6: RohrPost.vbs
Unterthema: Listing 7: StopTime.vbs
Unterthema: Listing 8: Viewer.vbs
Der Ruf des Windows Script Host hat in letzter Zeit arg gelitten, weil ihn viele VBScript-Viren missbrauchen (siehe Kasten `Sicher skripten´ unten). Das ist schade, denn er bietet sehr wertvolle Möglichkeiten zum Automatisieren von Betriebssystem und Anwendungsprogrammen, was Praxisbeiträge in c't schon mehrfach bewiesen haben.
Seit Version 2.0 unterstützt der Windows Script Host das Arbeitsprinzip Drag & Drop, wenigen Anwendern auch als `Ziehen und Ablegen´ bekannt. Dabei startet ein Skript automatisch, sobald man ein oder mehrere Datei- beziehungsweise Ordnerobjekte auf dessen Symbol ablegt. Damit das Skript die Objekte verarbeiten kann, stellt ihm Windows deren Pfade in der Arguments-Liste zur Verfügung. So weit die Theorie. In der Praxis bedeutet das nahezu unbegrenzte Erweiterungsmöglichkeiten für den Windows-Desktop durch Tools, die sich nicht nur unschlagbar simpel und intuitiv bedienen lassen, sondern darüber hinaus auch von jedem Anwender mit grundlegenden Kenntnissen einer Skriptsprache selbst zu bauen sind.
Die acht in VBScript verfassten Skripte in diesem Beitrag dienen einerseits Mausartisten als fertige Helferlein und andererseits Skriptautoren als Beispiele und Anregungen für eigene Desktop-Erweiterungen: Dir2Doc.vbs überführt das Inhaltsverzeichnis eines gedroppten Ordners in editierbaren Text. DirInfo.vbs stellt den Speicherbedarf aller Unterordner eines gedroppten Ordners in Form eines Kreisdiagramms dar. FileBackup.vbs komprimiert und sichert gedroppte Dateien oder Ordner in einer täglich neu angelegten Zip-Datei. MailPost.vbs komprimiert ebenfalls gedroppte Dateien oder Ordner in einer Zip-Datei, hängt diese aber einer neuen E-Mail-Nachricht als Attachment an. MP3Play.vbs generiert eine Abspielliste (M3U-Datei) aus gedroppten MP3-Dateien/Ordnern und bringt deren Inhalt zu Gehör. RohrPost.vbs ist der kürzeste Weg für den Dateiversand im Netzwerk. StopTime.vbs ermittelt die Ausführungs- respektive Bearbeitungszeit von gedroppten Anwendungen oder Dokumenten. Und Viewer.vbs schließlich verwandelt gedroppte PowerPoint-Präsentationen in Instant-Bildschirmschoner.
Der Kasten `Schritt für Schritt´ auf Seite 266 nennt die Systemvoraussetzungen, die zur Ausführung der Skripte erfüllt sein müssen, und liefert Tipps zum Anlegen sowie Zuweisen von individuellen Desktop-Symbolen. Bei jeder Form von Drag & Drop gilt es zudem ein Windows-internes Limit zu beachten. So ist der Übergabespeicher für Pfade und Pfadnamen auf rund 2000 Zeichen begrenzt. Man kann also nur eine begrenzte Anzahl von Dateien oder Ordnern auf einmal auf dem Desktop-Symbol ablegen. Wer den gesamten Inhalt eines Ordners verarbeiten möchte, sollte anstelle der einzelnen Dateien daher lieber den Ordner droppen, sofern es das jeweilige Skript unterstützt.
Dir2Doc.vbs überprüft zunächst mit Hilfe der GetFolder-Methode des FileSystemObject, ob das erste Element der Arguments-Liste den Pfad eines existierenden Ordners enthält. Sollte das nicht zutreffen, beendet sich das Skript (Wscript.Quit) mit einer entsprechenden MsgBox-Fehlermeldung. Verläuft die Prüfung dagegen erfolgreich, startet das Skript eine Instanz des Textprogramms Word (CreateObject-Anweisung) und speichert den Verweis darauf in der Objektvariablen objWD. Der anschließende With-Block macht die Word-Instanz sichtbar (Visible = True), fügt ihr ein neues Dokument hinzu (Documents.Add) und schreibt `Inhalt von´ sowie den Pfad des Ordners (objFolder.Path) in dessen erste Zeile. Danach richtet das Skript insgesamt vier Tabulatoren (zwei linksbündige bei 0,5 und 7 sowie zwei rechtsbündige bei 12 und 16 Zentimetern) für die exakte Ausrichtung der Ordnerinhalte ein.
Die erste For-Each-Next-Schleife übernimmt die Ausgabe der Unterordner, die in der SubFolders-Liste des Ordners enthalten sind. Bei jedem Unterordner schreibt die Schleife - jeweils nach einem Tabulatorzeichen (vbTab) - dessen Namen (Name-Eigenschaft), die zur Unterscheidung von Dateien dienende Kennzeichnung `<Verz>´, die Größe in Bytes (Size-Eigenschaft) sowie den Zeitpunkt der letzten Änderung (DateLastModified-Eigenschaft) in das Dokument. Die zweite For-Each-Next-Schleife erledigt Entsprechendes für die Dateien, die in der Files-Liste des Ordners gelistet sind, verzichtet dabei aber naturgemäß auf die `Verz´-Kennzeichnung. Am Ende seiner Arbeit schreibt das Skript noch die in intCount mitgezählte Anzahl sowie den in lngSize kumulierten Gesamtspeicherbedarf aller Verzeichniseinträge in das Dokument.
DirInfo.vbs beginnt seine Arbeit mit der Überprüfung, ob im ersten Arguments-Element (das den Indexwert Null trägt) der Pfad eines existierenden Ordners übergeben wurde. Wenn das nicht der Fall ist, moniert das Skript das Fehlen jeglicher Arbeitsgrundlage (MsgBox-Anweisung) und beendet sich dann selbst (Wscript.Quit). Im anderen Fall startet die CreateObject-Anweisung eine neue Excel-Instanz und speichert den Verweis darauf in der Objektvariablen objXL. Sofern der Start erfolgreich war, bringt das Skript die zunächst unsichtbare Excel-Instanz zum Vorschein (Visible = True) und fügt ihr eine neue Arbeitsmappe hinzu (WorkBooks.Add). Die For-Each-Next-Schleife durchläuft die SubFolders-Liste des Ordners und füllt die ersten beiden Spalten des Arbeitsblatts `Tabelle1´ mit den Namen (objSubFolder.Name) und Größen (objSubFolder.Size) sämtlicher Unterordner. Die Charts.Add-Anweisung bringt ein neues Diagramm hervor, dessen Eigenschaften im nachfolgenden With-Block festgelegt werden. Das Setzen der ChartType-Eigenschaft auf xl3DPie veranlasst das Kalkulationsprogramm zum Anlegen eines 3D-Kreisdiagramms. Die SetSourceData-Zeile bestimmt den gesamten genutzten Bereich (UsedRange) von `Tabelle1´ zur Datenquelle des Diagramms, das als neues Blatt innerhalb der Arbeitsmappe (Location-Anweisung) erstellt werden soll. Die folgenden beiden Skriptzeilen verordnen dem Diagramm einen Titel (HasTitle = True), dessen Text (ChartTitle.Characters.Text) aus `Inhalt von´ und dem Pfad des gedroppten Ordners besteht.
Der If-Block fragt die Versionsnummer von Excel ab. Im Fall von Excel XP (objXL.Version = `10.0´) ordnet er das Abschalten der Diagrammlegende (HasLegend = False) an. An deren Stelle setzt die ApplyDataLabels-Anweisung eine wesentlich übersichtlichere Form der Datenbeschriftung, die zu jedem Kreissegment nicht nur die Größe des Unterordners, sondern auch dessen Namen aufführt. Da eine solche kombinierte Datenbeschriftung in früheren Excel-Versionen (bis einschließlich 2000) nicht möglich ist, verordnet der Else-Block die Anzeige der Legende sowie eine Datenbeschriftung, die ausschließlich Größenangaben enthält. Die eindeutige Zuordnung von Datenwerten und deren Namen ist dabei - wie bei allen handgemachten Diagrammen auch - nur über die in der Legende dokumentierten Farben möglich, was für Farbenblinde (dazu zählt man allein zehn Prozent der männlichen Bevölkerung) ein oft unüberwindbares Hindernis ist. Für diese Anwendergruppe stellt die erweiterte Datenbeschriftung von Excel XP eine echte Arbeitserleichterung dar, die mehr als Smart-Tags & Co ein Upgrade auf die neue Excel-Version rechtfertigen kann.
Die Arbeit von FileBackup.vbs beginnt mit dem Zählen der Arguments-Elemente. Falls deren Count-Wert Null beträgt, wurde das Skript anscheinend per Doppelklick und nicht durch eine Drag&Drop-Aktion gestartet, was eine entsprechende Fehlermeldung per MsgBox sowie das vorzeitige Skriptende (Wscript.Quit) nach sich zieht. Im Fall von ordnungsgemäß gedroppten Dateien oder Ordnern liest das Skript den Installationspfad des Komprimierprogramms WinZip aus der Systemregistrierung (RegRead-Anweisung) und speichert diesen in der Variablen strWinZipPfad. Sollte die Variable leer ("") sein, ist WinZip nicht installiert, was ebenfalls zu einer Fehlermeldung und zum Skriptabbruch führt. Wenn auch diese Hürde erfolgreich genommen ist, liest FileBackup.vbs den Pfad des Sicherungsordners aus dem in strRegKey gespeicherten Schlüssel der Systemregistrierung.
Sollte der Schlüssel nicht existieren (was beim ersten Aufruf des Skripts die Regel ist), aktiviert das Skript das ActiveX-Control DlgTools.ocx per CreateObject-Anweisung, um dem Anwender über dessen DlgOpenFolder-Methode die Auswahl des Sicherungsordners mit dem dafür vorgesehenen Standarddialog des Betriebssystems zu ermöglichen. Den Pfad des gewählten Ordners speichert die RegWrite-Anweisung in besagtem Registry-Schlüssel. Die mit strZieldatei beginnende Zeile definiert den Pfadnamen der anzulegenden Zip-Datei, deren Dateinamen sich aus dem zweistellig formatierten Jahr, Monat und Tag des aktuellen Datums - jeweils durch einen Bindestrich getrennt - und der Extension `.zip´ zusammensetzt. Die Sicherungsdatei für den 29. September 2001 würde demnach den Dateinamen 01-09-29.zip tragen. Die Reihenfolge der Datumsbestandteile stellt übrigens sicher, dass der Windows-Explorer die Zip-Dateien in chronologischer Reihenfolge anzeigt.
Die For-Next-Schleife hangelt sich der Reihe nach durch alle in Arguments enthaltenen Pfadnamen und übergibt diese in Anführungszeichen (Chr(34)) eingeschlossen dem per Run-Anweisung gestarteten WinZip-Programm zwecks Aufnahme in die Archivdatei (strZielDatei). Die WinZip-Optionen `-min´ und `-a´ veranlassen das Packprogramm zur Minimierung seines Programmfensters und zum Hinzufügen der Inhalte in das Zip-Archiv (die Syntax der WinZip-Befehlszeile und weitere Optionen sind im Kasten `WinZip per Befehlszeile steuern´ auf Seite 274 dokumentiert). Sofern es bei der Ausführung des Komprimierprogramms zu einem Fehler kommt, meldet das Skript dem Anwender die WinZip-interne Fehlernummer (intErrCode) und beendet sich dann per Wscript.Quit-Anweisung. Nach durchweg erfolgreichen Aufrufen des Packprogramms verkündet FileBackup.vbs die Anzahl der gesicherten Dateien und/oder Ordner.
Wie sein nächster Verwandter FileBackup.vbs (siehe diese Seite) prüft MailPost.vbs zunächst, ob es per Drag & Drop oder Doppelklick gestartet wurde, und checkt danach, ob das Komprimierprogramm WinZip vorhanden ist (mindestens in Version 7.0). Das Skript komprimiert die gedroppten Explorer-Inhalte in der Datei Anlagen.zip, die es standardmäßig im Temp-Verzeichnis des Systems anlegt. Damit nicht unversehens Anhänge früherer Mails mitverschickt werden, prüft MailPost.vbs mit Hilfe der FileExists-Methode, ob die Zip-Datei schon besteht, um diese dann gegebenenfalls per Delete-Methode zu löschen.
Die For-Next-Schleife kleidet der Reihe nach jeden in Arguments enthaltenen Pfadnamen in Anführungszeichen (um Probleme mit eingeschlossenen Leerzeichen zu vermeiden) und übergibt ihn zur Archivierung an das per Run-Befehl gestartete WinZip. Sollte das Komprimierprogramm dabei einen Fehler produzieren, beendet sich das Skript und nennt den WinZip-internen Fehlercode, der in intErrCode gemeldet wird. Bei einem positiven Ausgang der Archivierungsarbeiten startet MailPost.vbs eine unsichtbare Outlook-Instanz per CreateObject-Anweisung. Sofern das gelingt, legt das Skript via CreateItem-Methode eine neue Nachricht an und fügt dieser die Zip-Datei als Anlage hinzu (objMail.Attachments.Add). Die Display-Methode macht die Nachricht sichtbar, sodass der Anwender den Empfänger auswählen und den Nachrichtentext verfassen kann.
Programmiertechnisch startet MP3Play.vbs mit der obligatorischen Prüfung der Arguments-Liste auf darin enthaltene Pfadnamen. Danach bindet das Skript besagtes ActiveX-Control ein (CreateObject-Anweisung) und nutzt dessen DlgOpenSaveFile-Funktion zur Abfrage des Dateinamens, unter dem die Abspiellistendatei gespeichert werden soll. Nachdem sich der Anwender für einen Dateinamen entschieden und das Dialogfeld per OK-Schaltfläche beendet hat, öffnet MP3Play.vbs unter dem gewählten Namen eine neue Textdatei (OpenTextFile-Anweisung). Dabei überschreibt es eine bestehende namensgleiche Datei ohne Warnung. Wer zart besaitet ist, sollte das Skript daher an dieser Stelle um eine FileExists-Prüfung mit anschließender InputBox-Nachfrage beim Anwender - `Sind Sie sicher?´ - erweitern. Denkbar wäre auch eine Änderung des zweiten Arguments der OpenTextFile-Anweisung von 2 auf 8. Damit würden die Pfadnamen der gedroppten Dateien an eine bestehende Datei angehängt.
Die For-Next-Schleife hangelt sich der Reihe nach durch alle in Arguments enthaltenen Pfadangaben und prüft per FolderExists-Methode, ob diese auf eine Datei oder einen Ordner verweisen. Im ersten Fall schreibt das Skript den Pfadnamen selbst in die Playliste. Im zweiten Fall durchsucht die For-Each-Next-Schleife die Files-Liste des gedroppten Ordners nach MP3-Dateien und verewigt deren Pfadnamen (objDatei.Path) in der M3U-Datei. Der Aufruf des Run-Befehls am Ende des Skripts startet den Media-Player und übergibt ihm die Abspiellistendatei zwecks Wiedergabe.
RohrPost.vbs startet mit der üblichen Überprüfung der Arguments-Liste auf gedroppte Dateien/Ordner und legt dann in der Variablen strZielordner den Pfad des `kollegialen´ Desktop-Ordners fest. Der beginnt standardmäßig und in der üblichen UNC-Notation (Uniform Naming Convention) mit einem doppelten Backslash (`\\´), dem Netzwerknamen des Computers, einem einfachen Backslash sowie dem Laufwerksbuchstaben ohne Doppelpunkt. Den Rest bildet eine Backslash-getrennte Abfolge von Ordnernamen, wie sie auch in Windows-üblichen Pfadangaben zu finden ist. Der im Skript verwendete (und nach eigenem Bedarf anzupassende) Beispielpfad \\Henkelmann\C\WINDOWS\Desktop verweist also auf den Ordner C:\Windows\Desktop des Netzwerk-Rechners `Henkelmann´. RohrPost.vbs prüft, ob der Netzwerkordner vorhanden und bereit ist. Dazu verwendet das Skript nicht die bei PC-übergreifenden Aktionen unzuverlässige GetFolder-Methode des FileSystemObject, sondern die NameSpace-Methode des Shell.Application-Objekts, das die mit dem Internet Explorer 4.0 eingeführten Desktop-Erweiterungen repräsentiert. Wenn die Bereitschaft des Ordners bestätigt ist, kopiert die For-Next-Schleife alle gedroppten Dateien respektive Ordner (deren Pfadangaben in Arguments bereitstehen) hinein. Dazu nutzt sie die CopyHere-Methode des oben erwähnten Shell.Application-Objekts. Die diversen Kopiermethoden des FileSystemObject eignen sich nicht, da sie sich beharrlich weigern, über die Grenzen des eigenen PC hinaus zu agieren - selbst wenn der Zielordner ausdrücklich freigegeben ist.
Ein Hinweis für Windows-Praktiker: Das Anlegen einer Desktop-Verknüpfung mit dem Desktop-Ordner des Kollegen erfüllt zwar prinzipiell den gleichen Zweck wie das abgedruckte Skript, prüft aber im Gegensatz zu diesem nicht, ob die Netzwerkverbindung besteht. Außerdem bietet nur ein Skript die Möglichkeit, die Funktion der Desktop-Pipeline individuell zu erweitern, beispielsweise durch eine Komprimierfunktion nach dem Vorbild von FileBackup.vbs.
Die Programmierung des Skripts ist wenig aufwendig. Sie beginnt mit einem Check des ersten Arguments-Elements, in dem sich der Pfadname der gedroppten Programm- oder sonstigen Datei befinden sollte. Bei einem Skriptstart per Doppelklick ist die Arguments-Liste dagegen leer, was StopTime.vbs mit einer passenden Fehlermeldung und der nachfolgenden Selbstterminierung per Wscript.Quit quittiert. Sofern aber das Droppen einer Datei als bewiesen gilt, speichert das Skript den aktuellen Timer-Wert (der die Anzahl der seit Mitternacht vergangenen Sekunden enthält) in der Variablen lngStart und startet die Datei umgehend per Run. Im Unterschied zur Shell-Funktion von VB(A) versteht sich diese Anweisung nicht nur aufs Ausführen von Programmen - also etwa EXE-, COM- oder BAT-Dateien -, sondern auch auf das Öffnen von registrierten Dateitypen in ihrer zugehörigen Anwendung. Der Run-Start einer DOC-Datei aktiviert also das Textprogramm Word und veranlasst es zum sofortigen Öffnen des Dokuments. Ein weiterer Vorteil der Run-Anweisung ist ihr drittes Argument, das, auf True gesetzt, die Skriptausführung pausieren lässt, bis der gestartete Prozess beendet wurde. StopTime.vbs nutzt dieses Feature für ein ressourcenschonendes Nickerchen, ehe es vom Programmende geweckt wird. Anschließend berechnet es mit frischen Kräften die Anzahl der zwischenzeitlich verflossenen Sekunden (durch das Abziehen von lngStart vom aktuellen Timer-Wert) und präsentiert das Ergebnis im übersichtlichen Stunden-Minuten-Sekunden-Format per MsgBox-Dialog.
Zu Beginn seiner Arbeit stellt Viewer.vbs sicher, dass ihm überhaupt eine Datei per Drag & Drop übergeben wurde. Danach liest das Skript den Installationspfad des PowerPoint-Viewers aus dem in strRegKey gespeicherten Schlüssel der Systemregistrierung. Sofern der Schlüssel noch nicht existiert, aktiviert Viewer.vbs das ActiveX-Control DlgTools.ocx (CreateObject-Anweisung) und nutzt dessen DlgOpenSaveFile-Funktion zur Darstellung des Windows-eigenen Standarddialogs Datei öffnen, mit dem der Anwender den Standort der Programmdatei PPView32.exe auswählen kann. Die RegWrite-Methode speichert den zurückgelieferten Pfadnamen dann für den zukünftigen Gebrauch in der Registry. Mit der Run-Anweisung startet das Skript die Viewer-Anwendung und übergibt ihr den in Anführungszeichen gesetzten Pfadnamen (objFile.Path) der gedroppten Datei.
Dank ihrer Drag&Drop-Fähigkeiten haben Skripte also das Zeug zu (fast) ausgewachsenen Programmen. Weitere Beispiele, die vielleicht zu ganz neuen Permutationen anregen, finden sich in [5] und [6]. Wer ein wenig mit dem Script Host experimentiert, wird vielleicht auch so manches Vorurteil revidieren ... (se)
[2] DlgTools.ocx und Skriptdateien auf heise online: www.heise.de/ct/ftp/listings.shtml
[3] PowerPoint-97-Viewer: http://office.microsoft.com/germany/downloads/9798/p/ppview97.aspx
[4] WinZip-Testversion: www.winzip.de
[5] Dr. Tobias Weltner: Zaubern mit Windows, Mehr Komfort beim Automatisieren: Scripting Host 2.0 und VBScript 5.0, c't 21/99, S. 294
[6] Dr. Tobias Weltner: Windows im Griff, Mit dem Scripting Host wird das System erst rund, c't 10/99, Seite 96
Besonders gefährlich wird es, wenn Skripte ungefragt ausgeführt werden, etwa weil sie in einer E-Mail stecken und vom zuständigen Client direkt ausgeführt werden oder weil sie sich in Webseiten als so genannte `aktive Inhalte´ verbergen. Deshalb sollte man die aktiven Inhalte im Web-Browser unbedingt abschalten (beim Internet Explorer nur innerhalb der Zone `Internet´) und möglichst mit einem E-Mail-Programm arbeiten, das Anhänge nicht ungefragt öffnet. Die Sicherheitseinstellungen auf Ihrem System können Sie mit dem c't-Browser-Check auf heise online (www.heise.de/ct/browsercheck/) überprüfen. Detailliertere Angaben finden Sie im Artikel `Gute Einstellung´ (c't 21/01, S. 144), den Sie im Heise-Kiosk in digitaler Form nachbestellen können.
Einige Skripte setzten die Installation von weit verbreiteten Programmen und Tools voraus: Die Office-Anwendungen Word (Dir2Doc.vbs), Excel (DirInfo.vbs) und PowerPoint (Viewer.vbs) müssen mindestens in der Version 97 vorliegen, Outlook (MailPost.vbs) in der Version 2000 oder XP. Zu den benötigten Tools zählen der Windows Media Player 6.x (MP3Play.vbs) sowie das Packprogramm WinZip (FileBackup.vbs, MailPost.vbs) als Version 7 oder 8. Eine Testversion von letzterem ist unter [4] erhältlich. Und schließlich benötigen drei Skripte (FileBackup.vbs, MP3Play.vbs und Viewer.vbs) Zugriff auf das ActiveX-Control DlgTools.ocx, das auf heise online [2] zum Download bereitsteht und dessen Funktion im Kasten auf Seite 271 ausführlich beschrieben ist.
An den von Viewer.vbs benötigten PowerPoint-Viewer zu gelangen, ist weniger leicht. Das Tool gehört zwar zum Lieferumfang von PowerPoint 2000, wird aber von dessen Setup-Routine nicht betriebsfertig installiert. Man muss es regelrecht gewinnen, indem man eine beliebige Präsentation mit Hilfe des Pack&Go-Assistenten komprimiert und über dessen Auspackroutine PngSetup.exe wieder in einen beliebigen Zielordner extrahiert. In diesem finden sich dann die Programmdatei PPView32.exe nebst einigen DLLs, die zusammengenommen den PowerPoint-Viewer ausmachen. In den derzeit ausgelieferten Versionen von PowerPoint XP sucht man den Viewer vergebens. Auch über den im Programm genannten Link auf die Download-Seiten von Microsoft lässt er sich nicht nachrüsten. Anwender von PowerPoint XP können sich derzeit (November 2001) nur mit einem Rückgriff auf die 2000er-Version des Viewers behelfen. Allerdings unterstützt das Programm die neuen Animationseffekte von PowerPoint XP nicht. Einen Viewer für PowerPoint 97 stellt Microsoft unter [3] zur Verfügung.
Zum Anlegen der Skripte genügt der Windows-Editor Notepad. Alternativ lässt sich jedes Textprogramm verwenden, das ein Abspeichern im reinen Textformat unterstützt. Wer sich das Abtippen der Listings ersparen möchte, kann sich mit dem ActiveX-Control DlgTools.ocx gleich auch die fertigen Skriptdateien von heise online [2] besorgen. Egal, ob abgetippt oder heruntergeladen: Man sollte die VBS-Dateien nicht direkt auf dem Windows-Desktop (beziehungsweise den diesen repräsentierenden Desktop-Ordner) speichern, sondern in einem beliebigen anderen Verzeichnis, aus dem man sie bei gedrückten Strg- und Umschalttasten auf den Desktop zieht. Nur dann nämlich legt Windows eine Verknüpfung an, der man über den Kontextmenübefehl Eigenschaften ein individuelles Symbol zuweisen kann, welches die Funktion des jeweiligen Dropdown-Ziels besser vermittelt als das uniforme Skript-Icon. Als Quellen für die alternativen Symbole kommen beispielsweise die im Systemverzeichnis zu findenden Dateien Shell32.dll und Moricons.dll sowie ein unerschöpflicher Fundus von Shareware-Icon-Sammlungen in Frage.
Set objDlgTools = WScript.CreateObject("DesktopSkripte.DlgTools")Die Methode liefert einen Verweis auf das Control zurück, der per Set-Anweisung in einer Objektvariablen (hier objDlgTools) gespeichert wird. Über die Objektvariable kann man dann direkt auf die zwei Funktionen von DlgTools.ocx zugreifen.
Die erste Funktion trägt den Namen DlgOpenFolder und ist für den Aufruf des Windows-eigenen Ordner-suchen-Dialogs zuständig. Das einzige Argument legt den Eingabeaufforderungstext des Dialogfelds fest. Als Funktionswert liefert DlgOpenFolder den Pfad des gewählten Ordners beziehungsweise eine leere Zeichenkette nach Abbruch des Dialogs zurück. Aufrufbeispiel:
strOrdner = objDlgTools.DlgOpenFolder("Wählen Sie den Sicherungsordner:")Die zweite Funktion heißt DlgOpenSaveFile und ist für die Auswahl von Dateinamen zuständig. Zum Aufruf des Öffnen-Dialogs ist dem ersten Funktionsargument der Wert 1, für den Speichern-unter-Dialog der Wert 2 zuzuweisen. Das zweite Argument übermittelt eine Beschreibung des zu öffnenden Dateityps (wie `Anwendungen´ oder `Word-Dokumente´), das dritte die dem Dateityp entsprechende Filtermatrix (`*.exe´ oder `*.doc´). Im vierten Argument kann man einen Dateinamen übergeben, der als Vorgabewert erscheint. Argument Nummer fünf ermöglicht die Angabe eines Pfades (`C:\Eigene Dateien´), der den Startordner des Dialogfelds bestimmt. Das sechste Argument schließlich legt den Dialogfeldtitel fest. Wenn die letzten drei Argumente leere Zeichenketten enthalten, greift die Funktion auf Standardwerte zurück. Aufrufbeispiel:
strDatei = objDlgTools.DlgOpenSaveFile(1, "Text-Dateien", "*.txt", "Beispiel.txt", _ "C:\Eigene Dateien", "Wählen Sie eine Textdatei ")Kasten 4
Winzip32.exe [-min] Aktion [Optionen] Archivdatei[.zip] Dateiname
Winzip32.exe -e [Optionen] Archivdatei[.zip] Verzeichnis
Dim objFS Dim objFolder Dim objWD Dim objSubFolder Dim objFile Dim intCount Dim lngSize Const wdAlignTabRight = 2 Const wdAlignTabLeft = 0 Const wdTabLeaderDots = 1 Const wdTabLeaderSpaces = 0 On Error Resume Next Set objFS = WScript.CreateObject("Scripting.FileSystemObject") Set objFolder = objFS.GetFolder(WScript.Arguments(0)) If objFolder Is Nothing Then MsgBox "Kein Ordner gedroppt.", vbInformation, WScript.ScriptName WScript.Quit End If Set objWD = WScript.CreateObject("Word.Application") If objWD Is Nothing Then MsgBox "Word kann nicht gestartet werden.", vbInformation, _ WScript.ScriptName WScript.Quit End If With objWD .Visible = True .Documents.Add With .Selection .TypeText "Inhalt von " & objFolder.Path & vbCR With .ParagraphFormat.TabStops .ClearAll .Add objWD.CentimetersToPoints(0.5), wdAlignTabLeft, _ wdTabLeaderSpaces .Add objWD.CentimetersToPoints(7), wdAlignTabLeft, _ wdTabLeaderDots .Add objWD.CentimetersToPoints(12), wdAlignTabRight, _ wdTabLeaderDots .Add objWD.CentimetersToPoints(16), wdAlignTabRight, _ wdTabLeaderDots End With For Each objSubFolder In objFolder.SubFolders .TypeText vbTab & UCase(objSubFolder.Name) & vbTab _ & "<Verz>" & vbTab & FormatNumber(objSubFolder.Size, _ 0, , , True) & " Bytes" & vbTab & _ objFolder.DateLastModified & vbCR intCount = intCount + 1 lngSize = lngSize + objSubFolder.Size Next For Each objFile In objFolder.Files .TypeText vbTab & LCase(objFile.Name) & vbTab & vbTab _ & FormatNumber(objFile.Size, 0, , , True) & " Bytes" _ & vbTab & objFile.DateLastModified & vbCR intCount = intCount + 1 lngSize = lngSize + objFile.Size Next .TypeText intCount & " Einträge, " & FormatNumber(lngSize, _ 0, , , True) & " Bytes" End With End WithKasten 6
Dim objFS Dim objFolder Dim objXL Dim objSubFolder Dim intZeile Const xl3DPie = -4102 Const xlColumns = 2 Const xlLocationAsNewSheet = 1 Const xlColorIndexNone = -4142 Const xlLineStyleNone = -4142 Const xlDataLabelsShowValue = 2 On Error Resume Next Set objFS = WScript.CreateObject("Scripting.FileSystemObject") Set objFolder = objFS.GetFolder(WScript.Arguments(0)) If objFolder Is Nothing Then MsgBox "Kein Ordner gedroppt.", vbInformation, WScript.ScriptName WScript.Quit End If Set objXL = WScript.CreateObject("Excel.Application") If objXL Is Nothing Then MsgBox "Excel kann nicht gestartet werden.", vbInformation, _ WScript.ScriptName WScript.Quit End If With objXL .Visible = True .WorkBooks.Add For Each objSubFolder In objFolder.SubFolders intZeile = intZeile + 1 .ActiveSheet.Cells(intZeile, 1).Value = objSubFolder.Name .ActiveSheet.Cells(intZeile, 2).Value = objSubFolder.Size Next .ActiveSheet.UsedRange.Columns(2).Cells.NumberFormat = "#,##0" .Charts.Add With .ActiveChart .ChartType = xl3DPie .SetSourceData objXL.Sheets("Tabelle1").UsedRange, xlColumns .Location xlLocationAsNewSheet .HasTitle = True .ChartTitle.Characters.Text = "Inhalt von " & objFolder.Path If objXL.Version = "10.0" Then .HasLegend = False .ApplyDataLabels , , , , , True, True, False Else .HasLegend = True .ApplyDataLabels xlDataLabelsShowValue End If .PlotArea.Interior.ColorIndex = xlColorIndexNone .PlotArea.Border.LineStyle = xlLineStyleNone End With End WithKasten 7
Dim objShell Dim objFS Dim strWinZipPfad Dim strRegKey Dim strBackupOrdner Dim objDlgTools Dim strZieldatei Dim strQuelldatei Dim intI Dim intCounter Dim intErrCode On Error Resume Next Set objShell = WScript.CreateObject("WScript.Shell") Set objFS = WScript.CreateObject("Scripting.FileSystemObject") If WScript.Arguments.Count = 0 Then MsgBox "Keine Dateien oder Ordner gedroppt.", vbInformation, _ WScript.ScriptName WScript.Quit End If strWinZipPfad = objShell.RegRead("HKLM\SOFTWARE\Microsoft" & _ "\Windows\CurrentVersion\App Paths\winzip32.exe\") If strWinZipPfad = "" Then MsgBox "WinZip ist nicht installiert.", vbCritical, WScript _ .ScriptName WScript.Quit End If strRegKey = "HKCU\Software\DesktopSkripte\BackupOrdner" strBackupOrdner = objShell.RegRead(strRegKey) If objFS.FolderExists(strBackupOrdner) = False Then Set objDlgTools = WScript.CreateObject("DesktopSkripte.DlgTools") If objDlgTools Is Nothing Then MsgBox "DlgTools.ocx ist nicht installiert.", vbInformation, _ WScript.ScriptName WScript.Quit End If strBackupOrdner = objDlgTools.DlgOpenFolder _ ("Bitte wählen Sie den Sicherungsordner:") If objFS.FolderExists(strBackupOrdner) = True Then objShell.RegWrite strRegKey, strBackupOrdner Else MsgBox "Kein gültiger Sicherungsordner.", vbCritical, _ WScript.ScriptName WScript.Quit End If End If If Right(strBackupOrdner, 1) <> "\" Then strBackupOrdner = strBackupOrdner & "\" End If strZieldatei = strBackupOrdner & Right(Date, 2) & "-" & Mid _ (Date, 4, 2) & "-" & Left(Date, 2) & ".zip" For intI = 0 To WScript.Arguments.Count - 1 strQuelldatei = Chr(34) & WScript.Arguments(intI) & Chr(34) intErrCode = objShell.Run(strWinZipPfad & " -min -a " & _ strZieldatei & " " & strQuelldatei, 1, True) If intErrCode <> 0 Then MsgBox "WinZip-Fehler " & CStr(intErrCode) & _ " aufgetreten.", vbCritical, WScript.ScriptName WScript.Quit Else intCounter = intCounter + 1 End If Next MsgBox CStr(intCounter) & " Datei(en) oder Ordner in " & _ strZieldatei & " gesichert.", vbInformation, WScript.ScriptNameKasten 8
Dim objShell Dim objFS Dim objSysEnv Dim strWinZipPfad Dim strZielOrdner Dim strZieldatei Dim objFile Dim intI Dim strQuelldatei Dim intErrCode Dim objOL Dim objMail On Error Resume Next Set objShell = WScript.CreateObject("WScript.Shell") Set objFS = WScript.CreateObject("Scripting.FileSystemObject") Set objSysEnv = objShell.Environment("PROCESS") If WScript.Arguments.Count = 0 Then MsgBox "Keine Dateien oder Ordner gedroppt.", vbInformation, _ WScript.ScriptName WScript.Quit End If strWinZipPfad = objShell.RegRead("HKLM\SOFTWARE\Microsoft" & _ "\Windows\CurrentVersion\App Paths\winzip32.exe\") If strWinZipPfad = "" Then MsgBox "WinZip ist nicht installiert.", vbCritical, WScript _ .ScriptName WScript.Quit End If strZielOrdner = objSysEnv("temp") If Right(strZielOrdner, 1) <> "\" Then strZielOrdner = strZielOrdner & "\" End If strZieldatei = strZielOrdner & "Anlagen.zip" If objFS.FileExists(strZieldatei) Then Set objFile = objFS.GetFile(strZieldatei) objFile.Delete End If For intI = 0 To WScript.Arguments.Count - 1 strQuelldatei = Chr(34) & WScript.Arguments(intI) & Chr(34) intErrCode = objShell.Run(strWinZipPfad & " -min -a " & _ strZieldatei & " " & strQuelldatei, 1, True) If intErrCode <> 0 Then MsgBox "WinZip-Fehler " & CStr(intErrCode) & _ " aufgetreten.", vbCritical, WScript.ScriptName WScript.Quit End If Next Set objOL = WScript.CreateObject("Outlook.Application") If objOL Is Nothing Then MsgBox "Outlook kann nicht gestartet werden.", vbInformation, _ WScript.ScriptName WScript.Quit End If Set objMail = objOL.Application.CreateItem(0) With objMail .Attachments.Add strZieldatei .Display End WithKasten 9
Dim objShell Dim objFS Dim objDlgTools Dim strM3UDateiname Dim objM3UDatei Dim objDatei Dim intI Dim strArg On Error Resume Next Set objShell = WScript.CreateObject("WScript.Shell") Set objFS = WScript.CreateObject("Scripting.FileSystemObject") If WScript.Arguments.Count = 0 Then MsgBox "Keine Dateien oder Ordner gedroppt.", vbInformation, _ WScript.ScriptName WScript.Quit End If Set objDlgTools = WScript.CreateObject("DesktopSkripte.DlgTools") If objDlgTools Is Nothing Then MsgBox "DlgTools.ocx ist nicht installiert.", vbInformation, _ WScript.ScriptName WScript.Quit End If strM3UDateiname = objDlgTools.DlgOpenSaveFile(2, _ "MediaPlayer-Abspiellisten", "*.m3u", "Playlist1.m3u", "", _ "Abspielliste speichern unter") If strM3UDateiname > "" Then Set objM3UDatei = objFS.OpenTextFile(strM3UDateiname, 2, True) With objM3UDatei For intI = 0 To WScript.Arguments.Count - 1 strArg = WScript.Arguments(intI) If objFS.FolderExists(strArg) = True Then For Each objDatei In objFS.GetFolder(strArg).Files If LCase(Right(objDatei.Name, 4)) = ".mp3" Then .WriteLine objDatei.Path End If Next Else .WriteLine strArg End If Next .Close End With objShell.Run "MPlayer2.exe " & strM3UDateiname End IfKasten 10
Dim objFS Dim objShellApp Dim strZielOrdner Dim objFolder Dim strPathName Dim objItem Dim intI On Error Resume Next Set objFS = WScript.CreateObject("Scripting.FileSystemObject") Set objShellApp = CreateObject("Shell.Application") If WScript.Arguments.Count = 0 Then MsgBox "Keine Dateien oder Ordner gedroppt.", vbInformation, _ WScript.ScriptName WScript.Quit End If 'Pfad des Zielordners nach eigenem Bedarf anpassen strZielOrdner = "\\Henkelmann\C\WINDOWS\Desktop" Set objFolder = objShellApp.NameSpace(strZielOrdner) If objFolder Is Nothing Then MsgBox "Der Zielordner ist nicht verfügbar.", vbCritical, _ WScript.ScriptName WScript.Quit End If For intI = 0 To WScript.Arguments.Count - 1 strPathName = WScript.Arguments(intI) If objFS.FolderExists(strPathName) = True Then Set objItem = objFS.GetFolder(strPathName) ElseIf objFS.FileExists(strPathName) = True Then Set objItem = objFS.GetFile(strPathName) End If objFolder.CopyHere objItem.Path NextKasten 11
Dim objShell Dim objFS Dim objFile Dim lngStart Dim lngSekunden On Error Resume Next Set objShell = WScript.CreateObject("WScript.Shell") Set objFS = WScript.CreateObject("Scripting.FileSystemObject") Set objFile = objFS.GetFile(WScript.Arguments(0)) If objFile Is Nothing Then MsgBox "Keine Datei gedroppt.", vbInformation, WScript.ScriptName WScript.Quit End If lngStart = Timer objShell.Run Chr(34) & objFile.Path & Chr(34), 1, True lngSekunden = Timer - lngStart MsgBox "Ausführungszeit von " & objFile.Name & ": " & vbCR & _ TimeSerial(0, 0, lngSekunden), vbInformation, WScript.ScriptNameKasten 12
Dim objShell Dim objFS Dim objFile Dim objDlgTools Dim strRegKey Dim strViewerApp On Error Resume Next Set objShell = WScript.CreateObject("WScript.Shell") Set objFS = WScript.CreateObject("Scripting.FileSystemObject") Set objFile = objFS.GetFile(WScript.Arguments(0)) If objFile Is Nothing Then MsgBox "Keine Datei gedroppt.", vbInformation, WScript.ScriptName WScript.Quit End If strRegKey = "HKCU\Software\DesktopSkripte\ViewerApp" strViewerApp = objShell.RegRead(strRegKey) If objFS.FileExists(strViewerApp) = False Then Set objDlgTools = WScript.CreateObject("DesktopSkripte.DlgTools") If objDlgTools Is Nothing Then MsgBox "DlgTools.ocx ist nicht installiert.", vbInformation, _ WScript.ScriptName WScript.Quit End If strViewerApp = objDlgTools.DlgOpenSaveFile(1, "Anwendungen", _ "*.exe", "PPView32.exe", "", "Viewer-Anwendung wählen") If objFS.FileExists(strViewerApp) = True Then objShell.RegWrite strRegKey, strViewerApp Else MsgBox "Viewer-Anwendung nicht gefunden.", vbCritical, _ WScript.ScriptName WScript.Quit End If End If objShell.Run Chr(34) & strViewerApp & Chr(34) & " " & Chr(34) & _ objFile.Path & Chr(34)