minpic01.jpg

Dr. Tobias Weltner

Windows im Griff

Mit dem Scripting Host wird das System erst rund

Für die unter DOS so beliebten Batch-Dateien hatte Microsoft in Windows zunächst keinen Nachfolger vorgesehen; eine programmierbare Schnittstelle zum System fehlte. Seit anderthalb Jahren gibt es eine, aber kaum jemand nutzt sie - und verschenkt damit interessante Möglichkeiten. Der Scripting Host ist nämlich das ideale Werkzeug, um komplexe und zeitaufwendige Arbeitsschritte zu automatisieren und verborgene Funktionen in Windows zu nutzen, an die man anders gar nicht oder nur schwer herankommt.

Unterthema: Weitere Artikel zum Scripting
Unterthema: Sicherheitsloch Scripting Host?
Unterthema: Listing MINI.VBS
Unterthema: Listing CLOSE.VBS
Unterthema: Listing DATUM.VBS
Unterthema: Listing WINDIR.VBS
Unterthema: Listing LOGBUCH.VBS
Unterthema: Listing FEHLER.VBS
Unterthema: Listing STARTBILD.VBS
Unterthema: Listing KONVERT.VBS
Unterthema: Listing DRUCKEN.VBS
Unterthema: Listing MSDOSSYS.VBS
Unterthema: Listing DOKU.VBS
Unterthema: Listing ICONS.VBS
Unterthema: Listing UMBENENNEN.VBS
Unterthema: Listing Benutzer.VBS
Unterthema: Listing SETUPDIR.VBS
Unterthema: Listing SAVE.VBS
Unterthema: Listing RESTORE.VBS
Unterthema: Listing Schriften
Unterthema: Listing EMAILZIP.VBS
Unterthema: Listing EMAILDAT.VBS

Bitte beachten Sie auch diese Ergänzung!

So mächtig der Windows Scripting Host ist - richtig durchgesetzt hat er sich noch nicht. Erstens bevorzugen viele Softwarefirmen ihre eigene Makrosprache, was die systemweite Verbreitung des WSH hemmt, und zweitens macht es Microsoft den Anwendern unnötig schwer, sich damit anzufreunden. Im Unterschied zu AppleScript von MacOS beispielsweise gibt es beim Scripting Host kein Recorderprogramm, das alle Arbeitsschritte aufnimmt und in Skripte oder Makros schreibt, die der Benutzer anschließend editieren und erweitern kann. Unter Windows muß man statt dessen jedes Skript `zu Fuß´ programmieren, eine für Einsteiger oft zu hohe Hürde. Im Vergleich mit AppleScript fehlt auch eine Möglichkeit herauszufinden, wie sich andere Programme fernsteuern lassen und welche Befehle sie kennen. Doch auch unter Windows kommt man schnell weiter, wenn man die nötigen Tricks kennt - die verraten wir Ihnen in diesem Heft.

Auf den kommenden 13 Seiten geht es zunächst darum, wie man den Scripting Host und damit Windows 95, 98 und NT selbst steuert. Die anschließenden Artikel zeigen an den Beispielen Internet Explorer/Netscape Communicator, Word und Corel Draw/Photo Paint, wie man auch in externen Applikationen nützliche Funktionen nachrüstet und mit Skripten oder Makros Zeit spart. Im Artikel ab Seite 134 stellen wir Ihnen überdies Makroprogramme vor, welche sozusagen die Lücke schließen, die Microsoft seit 1995 offenläßt: der Windows-Makrorecorder wurde ja mit Version 3.11 eingestellt. Wie man andere Programme mit Skriptsprachen automatisiert, zeigen wir in loser Folge in späteren Ausgaben.

Die abgedruckten Beispiele können Sie auf Anhieb einsetzen, ob Sie nun sporadisch oder regelmäßig mit den jeweiligen Programmen arbeiten. Damit Sie sie nach Ihren Bedürfnissen ergänzen oder umschreiben können, haben wir alle wesentlichen Funktionen in Kommentarzeilen erläutert. Freilich brauchen Sie die Listings nicht abzutippen, alle stehen bei heise online zum Download bereit [11].

In diesem ersten Artikel finden sich 20 Skripte für den Windows-Explorer; vom Mehrzeiler etwa für abwechselnde Startbilder oder ein Logbuch, das alle Windows-Starts samt Datum, Uhrzeit und Benutzernamen protokolliert, über recht aufwendige Programme, die zum Beispiel zeigen, wie man eine WYSIWYG-Liste aller installierten Schriften erstellt oder die komplizierte Registry fehlerfrei modifiziert, bis hin zu ausgewachsenen Applikationen. Mit zwei Skripten kann man beispielsweise alle Dateiverknüpfungen sichern und bei einem Schaden wiederherstellen - Windows selbst kennt keine derartigen Rettungsmaßnahmen; bislang mußte man im Notfall das System oder wenigstens das beschädigte Programm neu installieren.

Installation per Doppelklick

Unter Windows 98 wird der Scripting Host automatisch eingerichtet. Ob er aktiv ist, findet man in der Systemsteuerung unter Software heraus (Register Windows-Setup; Doppelklick auf Zubehör). Windows-95- und NT-Besitzer laden sich das Paket aus dem Internet [1] und installieren es kurzerhand. Wer sich ernsthaft mit der Skriptprogrammierung beschäftigen möchte - und das können wir nur empfehlen -, sollte sich auch die vollständige Dokumentation besorgen [2, 3], die jeweils im HTML-Format bereitsteht. Die Texte lassen sich zwar mit jedem beliebigen Web-Browser lesen; für eine echte kontextsensitive Hilfe sollte man aber die HTML-Hilfe verwenden, die bei Windows 98 zum Lieferumfang gehört und für ältere Systeme ebenfalls kostenlos bereitsteht [4].

minpic07.jpg

Der Windows Scripting Host ist in Windows 98 bereits eingebaut. Bei Windows 95 und NT kann man ihn kostenlos nachrüsten.

Der Scripting Host läßt sich in unterschiedlichen Sprachen programmieren; von Haus aus versteht er JScript und VBScript. Wo erfahrene Programmierer gerne JScript bevorzugen, weil die Skripte dann auch in JavaScript-fähigen Web-Browsern laufen, ist VBScript als Verwandter des Visual-Basic-Dialekts wesentlich leichter zu erlernen. Deshalb verwenden wir es auch als Grundlage für unsere Beispiele.

Skripte lassen sich mit jedem beliebigen Texteditor eintippen und bearbeiten; das mitgelieferte Notepad reicht vollkommen aus. Freilich können Sie auch eine Textverarbeitung verwenden, allerdings müssen Sie die Dateien dann `pur´, also ohne Auszeichnungen speichern. JScripts müssen die Dateiendung `.JS´ tragen, VBScript-Skripte `.VBS´. Dann führt der Scripting Host die Programme automatisch aus, wenn man sie per Doppelklick öffnet.

Mit Bordmitteln

Die hauseigenen WSH-Befehle sind vom übrigen System streng abgeschottet. Wie effizient sie sich trotzdem einsetzen lassen, zeigt das kleine Skript `Datum.VBS´. Es fragt nach einem beliebigen Datum und liefert den entsprechenden Wochentag zurück. Diesen muß es aber nicht selbst ausrechnen; die benötigte Funktion ist im Scripting Host eingebaut.

Der WSH enthält jedoch keine Befehle, um etwa auf das Dateisystem zuzugreifen oder irgendwelche anderen System-Eigenschaften zu verändern (siehe auch Kasten `Sicherheitsloch Skripting Host?´ auf Seite 100). Wirklich effiziente Skriptaktionen scheinen also zunächst zu scheitern.

Glücklicherweise läßt sich aber der Sprachschatz von VBScript fast beliebig erweitern. Mit dem Befehl CreateObject kann man nämlich die Funktionsaufrufe anderer Software benutzen, indem man Instanzen ihrer Objekte anlegt - ob es sich dabei um ActiveX-Objekte von Windows, um selbstgeschriebene oder um Programme anderer Hersteller handelt. Das Prinzip ist simpel: CreateObject("Name des Objektes") liefert ein Handle auf das Objekt zurück, das man per Set einer Variablen zuweist. Anschließend benutzt man diese Variable, um auf die Eigenschaften und Methoden des Objektes zuzugreifen, nachzuvollziehen etwa in dem simplen Skript WINDIR.VBS, welches den Pfad des Windows-Ordners ausgibt.

Als Teil der WSH-Installation kommen bereits einige Objekte mit, die man prächtig `mißbrauchen´ kann, unter anderem `Scripting.FileSystem-Object´, `WScript.Shell´ und `WScript.Network´. Das erste bereichert den Scripting Host um eine Vielzahl von Dateisystem-Befehlen, das zweite liefert Kommandos, um externe Programme auszuführen, Verknüpfungen zu organisieren oder auch die Registry zu bearbeiten, und das dritte fügt Netzwerkbefehle hinzu. All diese Objekte kommen auch in unseren Beispiel-Skripts zum Einsatz.

Anzapfen anderer Programme

Die Befehle der mitgelieferten Objekte sind in der WSH-Dokumentation ausführlich erläutert. Seine wahre Leistungsfähigkeit entfaltet der Scripting Host jedoch erst, wenn man auf Objekte anderer Programme zugreift. Deren Funktionsweise bleibt aber zunächst im Dunkeln. Weiter kommt man mit dem kostenlosen Spionage-Tool VBA Companion [5] oder auch dem Object Browser der VisualBasic Control Creation Edition [7]. Beide listen alle im System vorhandenen Automationsobjekte samt der darin enthaltenen Befehle und Eigenschaften auf. Dies allein ist allerdings nur eine Grundlage für eigene Experimente, denn längst nicht alle gelisteten Objekte lassen sich innerhalb von WSH-Skripten nutzen. Einige funktionieren nur in Zusammenhang mit laufenden Programmen, andere setzen voraus, daß ihre Bedienungsoberfläche in einer HTML-Seite eingebettet ist.

minpic05.jpg

Andere Programme lassen sich meist ebenfalls fernsteuern - welche Befehle sie kennen, ermittelt der kostenlose VBA Companion.

Trotzdem kann man mit den beiden Tools viele Juwelen ausgraben. Wer damit zum Beispiel die Microsoft Internet Controls öffnet, die mit dem Internet Explorer 4 installiert werden, findet das Objekt `Shell´, das vielfältige Befehle mitbringt, um die Windows-Oberfläche fernzusteuern. Man spricht es über CreateObject("Shell.Application") an und kann so in wenigen Zeilen beispielsweise das Skript MINI.VBS programmieren, das alle Fenster des Explorers per MinimizeAll-Aufruf minimiert und den Blick auf den Desktop freigibt. Ist die Arbeit darauf erledigt, klickt man einfach auf den OK-Button des zugehörigen Fensters, um die Fenster wieder sichtbar zu machen (UndoMinimizeAll).

Wer etwas tiefer in dieses System einsteigt und sich die Objekte und deren Zusammenspiel näher anschaut, kann sogar Automationsskripte wie CLOSE.VBS erstellen: Es schließt automatisch alle geöffneten Explorer-Fenster.

Um komplette Applikationen, wie etwa Excel, fernzusteuern, muß man sich natürlich zunächst einen Überblick darüber verschaffen, welche Applikationen überhaupt Automatisierungsschnittstellen bereitstellen und wie diese aussehen. Die dazu nötigen Werkzeuge bringt VisualBasic selbst in der kostenlosen Control Creation Edition mit. Eine Liste aller im System registrierten Klassenbibliotheken fördert der Befehl `Project - References´ zutage. Um die gewünschten in das aktuelle Projekt einzufügen und damit auch für den Object Browser zugänglich zu machen, markiert man das Kästchen vor dem jeweiligen Eintrag. Öffnet man danach den Object Browser (über das View-Menü oder einen Druck auf F2), so kann man sie in der Liste links oben auswählen und bekommt in der Liste `Classes´ alle Objekte angezeigt, die sich für eine Automatisierung eignen. Die Eigenschaften, Methoden und Ereignisse eines Objektes offenbaren sich rechts unten, nachdem man eine Klasse anklickt.

Nun sind die reinen Namen der Elemente oft nicht ausreichend. Programme, die eine offizielle Automatisierungsschnittstelle zur Verfügung stellen - dazu gehören unter anderem alle Microsoft-Office-Anwendungen - installieren daher neben der Klassenbibliothek auch eine Hilfe-Datei, deren Einträge der Object Browser durch einen Druck auf F1 oder das entsprechende Symbol zur Anzeige bringt.

Schatztruhe Internet

Im Netz der Netze finden sich unzählige ActiveX-Objekte, die den WSH um zusätzliche Befehle etwa für EMail-Versand oder Datenbankzugriff bereichern. Man kann sie meist kostenlos laden und in Windows registrieren. Wie das im einzelnen funktioniert, beschreiben wir am Schluß.

Der Grund für diesen unverhofften Softwaresegen liegt in einer recht unbekannten Verwandtschaft: Der Windows Scripting Host ist im Grunde nichts anderes als die lokale Version der Active Server Pages, einem Mechanismus, der im Internet-Information-Server von Windows NT zum Einsatz kommt. Active Server Pages, die man an der Extension .ASP erkennt, benutzen serverseitige VBScript- und JScript-Programme, um die Webseiten dynamisch zu generieren, sobald der Anwender sie abruft.

Dabei handelt es sich um exakt dieselbe Programmiersprache, die auch der WSH verwendet. Erweiterungsmodule für ASP funktionieren deshalb in aller Regel auch mit dem Windows Scripting Host und liefern so eine schier unüberschaubare Vielfalt von Zusatzbefehlen für eigene WSH-Skripte. Und umgekehrt können Sie Ihre WSH-Skripte auch direkt zur ASP-Programmierung benutzen, doch beachten Sie die Sicherheitslücken, die sich da auftun.

Im Eigenbau

Wer über etwas Programmiererfahrung in Visual Basic verfügt, kann sich sogar eigene ActiveX-Objekte schreiben. Das nötige Rüstzeug, die Visual Basic Control Creation Edition (VB CCE), stellt Microsoft sogar kostenlos bereit [7]. Dabei handelt es sich um die komplette Visual-Basic-Entwicklungsumgebung, die lediglich um die Fähigkeit beraubt wurde, EXE-Programme zu generieren. Mit der CCE aber ist es möglich, sämtliche Windows-API-Funktionen als ActiveX-Objekt zu kapseln und dann von WSH-Skripten aus via CreateObject anzusprechen.

Auch wenn die Erfinder des Scripting Hosts zunächst aus Sicherheitsgründen jeglichen Dateizugriff aus dem Sprachschatz gestrichen hatten, sind alle wichtigen Befehle quasi durch die Hintertür wieder eingewandert. Über das FileSystemObject läßt sich das gesamte Dateisystem des Rechners steuern. Erster Einsatz: ein Anmeldeprotokoll für Windows.

Logbuch

Jedesmal, wenn das Skript LOGBUCH.VBS aufgerufen wird, vermerkt es Datum und Uhrzeit sowie den Namen des angemeldeten Benutzers in der Datei C:\ANMELDUNG.LOG. Damit das Skript bei jedem Anmeldevorgang ausgeführt wird, plazieren Sie es einfach im Ordner `Autostart´. Beim Multibenutzerbetrieb gehört es in die Autostartgruppe für alle Benutzer. Die findet sich im Windows-Unterverzeichnis All Users\Startmenü\Programme\Autostart.

Eine entscheidende Rolle spielt der Befehl OpenTextFile, der Textdateien zum Lesen oder Schreiben öffnet. Per I/O-Modus 8 teilt man ihm mit, daß man neue Zeilen ans Textende anfügen möchte (Append). Im I/O-Modus 1 dagegen, dem Standardwert, läßt sich eine Datei mit OpenTextFile nur lesen, aber nicht verändern. Der dritte Parameter, den das Logbuch verwendet, vbTrue, sorgt dafür, daß die Datei neu angelegt wird, falls sie noch nicht existiert. Über WriteLine schließlich schreibt das Skript seine Textzeilen in die Datei.

Fehler jagen

Einen Programmierfehler quittiert der Scripting Host mit einem spröden Hinweis, der wenig mehr liefert als eine Zeilennummer. Damit Sie die betreffende Zeile nicht umständlich zählen müssen, was insbesondere bei langen Skripten schwerfällt, markiert das Skript FEHLER.VBS die fehlerhafte Zeile im VBS-Skript durch zwei auffällige Kommentarzeilen. Dadurch können Sie Fehler schneller und bequemer aufspüren. Nicht mehr benötigte alte Markierungen werden automatisch entfernt.

minpic06.jpg

Skripte werden besonders wertvoll, wenn man sie ins Kontextmenü integriert.

WSH-Skripte, die man häufiger benötigt, sollte man als Kontextmenü-Eintrag definieren; dann stehen sie stets auf Mausklick parat. Um etwa das Fehlerskript auf die rechte Maustaste zu legen, muß man es mit dem Dateityp von VB-Skripten verknüpfen. Den zuständigen Dialog `Ordneroptionen´ erreicht man vom Ansicht-Menü eines beliebigen Explorer-Fensters aus; bei Windows 98 zusätzlich über `Einstellungen´ im Startmenü. Öffnen Sie das Register `Dateitypen´ und wählen Sie aus der Liste den Eintrag `Skriptdatei für VBScript´. Klicken Sie auf Bearbeiten, anschließend auf Neu. Ins obere Feld des Fensters `Neuer Vorgang´ gehört der Name, unter dem Sie später den neuen Kontextmenü-Befehl sehen möchten - etwa `Fehler suchen´. Im unteren Feld folgt der Befehlsaufruf, zum Beispiel WSCRIPT.EXE C:\SCRIPTS\FEHLER.VBS "%L". Hinter WSCRIPT.EXE verbirgt sich der eigentliche Scripting Host. Das Programm muß dem Skriptnamen vorangestellt werden, weil VBS-Dateien für sich allein genommen nicht ausführbar sind. Die Systemvariable "%L" enthält später den langen Namen der Datei, über deren Kontextmenü der Anwender den Befehl aufgerufen hat. Diese Variable kann das VBS-Programm über WScript.Arguments abfragen. Fortan steht in jedem Menü, das sich per Klick auf eine Skriptdatei über die rechte Maustaste öffnet, der neue Eintrag `Fehler suchen´.

Startbild per Zufall

Abwechslung gefällig? Wer statt des offiziellen Windows-Logos ein anderes Bild beim Booten laden lassen möchte, findet im Internet tausende Varianten. Jede beliebige Bitmap-Datei, die im 256-Farben-Modus vorliegt und 320 x 400 Pixel mißt, funktioniert. Um Speicher zu sparen, skaliert Windows diese auf 640 x 400 Pixel hoch, was zu einer unschönen horizontalen Verzerrung führt. Die können Sie vermeiden, indem Sie Ihre Startbilder bereits im voraus auf die halbe Breite schrumpfen.

Das Skript STARTBILD.VBS aktiviert bei jedem Windows-Start ein anderes Bild und kopiert es in die Datei C:\LOGO.SYS - die lädt Windows als Startbild, sobald es sie vorfindet. (Gibt es diese Datei nicht, bevorzugt Windows seit Version 95b die Bitmap, die in C:\IO.SYS steht.) Am besten plazieren Sie das Skript in der Autostartgruppe, so daß es nach einem Windows-Start immer gleich das Bild für den nächsten Start eintragen kann.

Legen Sie einen Ordner C:\BILDER an und kopieren Sie all Ihre Lieblingsbilder hinein - mindestens aber eines, das zu LOGO.SYS mutieren kann. Der Ordner darf keine anderen Dateien enthalten. Ein individuelles Startbild, das Sie nicht verlieren möchten, kopieren Sie einfach vor dem ersten Start des Skriptes in den BILDER-Ordner, dann nimmt es an dem zufälligen Austauschprozedere teil. Funktioniert das Ganze hingegen gar nicht, ist bei Ihnen vermutlich die Startbildoption in der MSDOS.SYS-Datei abgeschaltet. Mit dem untenstehenden Skript MSDOSSYS.VBS können Sie das kurzerhand ändern: Tragen Sie LOGO=1 anstelle von LOGO=0 ein.

Schlußbild

Übrigens kann man mit demselben Verfahren auch die Bilder, die Windows beim Herunterfahren anzeigt (`Sie können den Computer jetzt ausschalten´ und `Der Computer wird heruntergefahren´) austauschen. Schreiben Sie das Skript einfach so um, daß es statt C:\LOGO.SYS die Dateien C:\WINDOWS\LOGOS.SYS respektive C:\WINDOWS\LOGOW.SYS ersetzt. Um Start- und Ausschaltbilder nicht durcheinanderzubringen, sollten Sie letztere freilich in einen anderen Ordner kopieren. Wer die Bilder nur nach eigenem Gusto ändern möchte, braucht nur deren Dateiendungen in .BMP zu ändern, um sie in Paint laden zu können. Nach den Änderungen muß man sie dann wieder in ihre Originalnamen umbenennen.

Beim Austausch von Texten zwischen unterschiedlichen Betriebssystemen gehen Sonderzeichen und deutsche Umlaute verloren, weil beispielsweise DOS, Windows und MacOS unterschiedliche Zeichencodes verwenden. Die Lösung: Das Skript KONVERT.VBS konvertiert fehlerhafte Sonderzeichen und sogar ganze Wörter oder Zeichenfolgen automatisch. In der Grundform wandelt das Skript die deutschen Umlaute von DOS-ASCII nach Windows-ANSI um. Man kann es aber leicht an andere Betriebssysteme anpassen oder für ganz andere Konvertierungsaufgaben verwenden, zum Beispiel um Umlaute in HTML-Sonderzeichen umzuwandeln, etwa per text = Replace(text, "ö", "ö").

Die Bedienung ist kinderleicht, weil das Skript die offiziellen Öffnen- und Speichern-Dialogfenster von Windows nutzt. Nachdem es die Datei eingelesen hat, ersetzt es per Replace beliebige Zeichencodes oder Textstrings. Anschließend speichert es die konvertierte Datei unter dem gewünschten Namen wieder ab.

Wenn Sie gleich viele hundert Dateien in einem Aufwasch konvertieren möchten, nehmen Sie - natürlich - ein Skript. Wie so etwas im Detail funktioniert, zeigt das Skript `Fortlaufende Seriennummern als Dateinamen´ weiter unten.

Dateilisten drucken

Sonderbarerweise enthält der Windows-Explorer noch immer keine Funktion, um eine Liste aller Dateien in einem Ordner auszudrucken. DRUCKEN.VBS behebt dieses Manko. Seine Funktionsweise ist einfach: Es beauftragt zuerst - unsichtbar - den DOS-Kommandozeileninterpreter damit, die eigentliche Dateiliste anzulegen, und konvertiert dann die DOS-Sonderzeichen in den Windows-konformen ANSI-Code. Anschließend öffnet es die Liste im Texteditor, von wo aus Sie sie drucken können.

Um den Kommandozeileninterpreter zu starten, benutzt das Skript den Run-Befehl des WScript.Shell-Objektes, der ein beliebiges Programm startet. Übergibt man etwa `Run command.com /c dir /on /og´, lädt der Interpreter und startet sogleich den Dir-Befehl. Die Optionen /on und /og sorgen für die alphabetisch sortierte Liste. Um weitere Funktionen kennenzulernen, können Sie per `Dir /?´ eine Übersicht aller Optionen des Dir-Kommandos anfordern.

Das Ergebnis des Dir-Befehls wird in eine Datei umgeleitet, die das Skript anschließend über OpenTextFile öffnet, liest, konvertiert und per CreateTextFile wieder in die Datei zurückschreibt. Da es sich um eine Textdatei handelt, wird diese automatisch vom gewählten Texteditor, üblicherweise Notepad, geladen - das Skript braucht dazu wiederum per Run lediglich die Textdatei aufzurufen. Auch dieses Skript bietet sich als Kontextmenü-Erweiterung an. Dazu gehen Sie vor wie beim Skript `Fehler jagen´, verknüpfen das Skript aber mit dem Dateityp `Ordner´.

Die Systemdatei MSDOS.SYS ist auch für Windows lebensnotwendig, weil sie elementare Details des Windows-Starts regelt. Da sie normalerweise mit den Attributen `Schreibgeschützt´ und `Versteckt´ vor Änderungen geschützt ist, kostet es etliche Klicks, bevor man Änderungen vornehmen kann. Das Skript MSDOSSYS.VBS zeigt, wie es einfacher geht: Es befreit die Datei von allen Schutzattributen, lädt den Inhalt im Editor und restauriert die Schutzattribute anschließend wieder.

Das Prinzip ist simpel. GetFile spricht die Datei an; Attributes liefert die augenblicklichen Attribute als Bitmaske. Wichtig: Nur vier Attribute haben Schreib/Lese-Status. Die übrigen Attribute dürfen nicht verändert werden, weil der Scripting Host sonst mit einer Zugriffsverletzung reagiert. Das Skript zeigt, wie man diese umgeht - vor dem Setzen von Attributen werden alle Read-Only-Attribute mittels And Not gelöscht. Wer Attribute setzen möchte, verwendet den Or-Operator.

Bei diesem Skript lohnt sich zudem ein Blick auf den Run-Befehl, der Notepad startet. Der dritte Parameter lautet vbTrue und sorgt dafür, daß das Skript so lange angehalten wird, bis Notepad wieder beendet ist. So ist es möglich, die Attribute nach der Änderung im Editor wieder in den Ursprungszustand zurückzuversetzen.

Dokumente-Menü reinigen

Das Dokumente-Menü im Startmenü ist eine nützliche Sache; es speichert automatisch die 15 zuletzt benutzten Dokumente für den schnellen Zugriff. Dabei geht Windows allerdings nicht sonderlich selektiv vor, sondern merkt sich alle Dateien, die der Anwender per Maus öffnet - also auch etwa Fonts oder ZIP-Dateien. Damit das Dokumente-Menü künftig nur interessante Dokumente auflistet, genügt ein Aufruf des Skriptes DOKU.VBS. Es untersucht alle Verknüpfungen im Dokumente-Menü respektive im zugrundeliegenden Ordner RECENT. Über CreateShortcut werden die Verknüpfungen geöffnet und das Ziel aus TargetPath erfragt. Entspricht das Ziel einem der erwünschten Dateitypen, die in der Variable als `erlaubt´ definiert wurden, dann bleibt der Eintrag erhalten, andernfalls wird er gelöscht.

Seit dem Internet Explorer 4 können endlich auch Ordner individuelle Icons tragen. Leider gibt es hierfür kein benutzerfreundliches Werkzeug; Microsoft hat diese interessante Möglichkeit offenbar für die eigenen Produkte reserviert. Das stellt das Skript ICONS.VBS ab.

Individuelle Ordner-Icons

Das Programm legt im Ordner eine Datei namens DESKTOP.INI an, fügt darin die nötigen Schlüsselwörter ein und verbirgt diese anschließend mit Hilfe der Schreibgeschützt- und System-Attribute. Mit diesen geheimen Insignien ausgestattet, zeigt jeder Ordner nach einer einmaligen Aktualisierung über die F5-Taste sein ganz persönliches Icon an.

Als Icon-Quelle können beliebige Systembibliotheken dienen: MORICONS.DLL, PROGMAN.EXE, SHELL32.DLL ... Auch ICO-Dateien und selbstgemalte Icons kommen in Frage: Im Malprogramm die Bildgröße auf 32 x 32 Punkte begrenzen und dann das Icon als Bitmap-Grafik mit der Dateiextension .ICO speichern. Freilich funktioniert auch dieses Skript am bequemsten, wenn man es als Kontextmenü-Erweiterung für den Dateityp Ordner definiert.

Fortlaufende Seriennummern

Internet, Digitalkameras, Scanner und Multimedia-Geräte produzieren immer unübersichtlichere Berge an Dateien. Wer beispielsweise Bilder in Ordnern archivieren, auf Web-Seiten plazieren oder als Grundlage für eine Animation verwenden möchte, mag vielleicht allen Dateien einheitliche Namen mit fortlaufenden Seriennummern geben, etwa Bild001.JPG, Bild002.JPG und so weiter. Von Hand ist dies ein zeitraubendes und fehlerträchtiges Unterfangen. Das Skript UMBENENNEN.VBS erledigt diese Aufgabe im Handumdrehen - vollautomatisch.

Es fragt zuerst nach dem Ordnernamen und dem Dateityp, um den sich das Skript kümmern soll, zum Beispiel `JPG´. Anschließend kann man ein Prefix eingeben, also eine Zeichenfolge, die der automatischen Seriennummer vorangestellt wird (`Bild´). Ohne Prefix-Angabe erhalten die Dateien eine reine Seriennummer als neuen Dateinamen. Das Skript ermittelt alle in Frage kommenden Dateien im angegebenen Ordner und speichert die Liste der Dateinamen im Variablenfeld dateiliste.

Die Architektur ist simpel: Der Ordner wird über GetFolder geöffnet und mittels for each datei in ordner.files Datei für Datei durchsucht - in der Reihenfolge, wie das Skript die Dateien vorfindet. Das FileSystemObject liefert über GetBaseName den Dateinamen und über GetExtensionName die Dateiendung zurück.

Durch einen kleinen Trick erweitern sich die Anwendungsmöglichkeiten des Skripts zusätzlich: Es beginnt stets mit der Seriennummer 0 und ermittelt in einer do-while...loop-Schleife automatisch, ob es bereits eine Datei mit der gerade aktuellen Seriennummer gibt. Falls ja, überspringt es diese Seriennummer und geht zur nächsten über. Kommen also neue Dateien hinzu, numeriert das Skript einfach weiter. Löscht man Dateien aus dem Ordner, dann füllt das Skript die dadurch entstandenen Lücken in den Seriennummern wieder auf. So erhält man stets eine durchgehende Reihe von Seriennummern. Bereits konvertierte Dateinamen werden nicht verändert.

Weil beim Vergleich die Groß- und Kleinschreibung keine Rolle spielen soll, vereinheitlicht das Skript die Schreibweise. Mit der Variable modus haben Sie die Wahl zwischen Klein- oder Großbuchstaben. Von diesem Zusatzeffekt profitieren Web-Autoren, die ausschließlich mit Kleinbuchstaben in Dateinamen arbeiten wollen. Falls Ihr Windows übrigens Dateinamen in Großbuchstaben nicht darstellt, ist die Option `Namen in Großbuchstaben ermöglichen´ in den Explorer-Einstellungen deaktiviert (Register `Ansicht´ im Dialog `Ordneroptionen´ unter Einstellungen im Startmenü).

Da das Skript nach der Sicherheitsabfrage unter Umständen große Mengen von Dateien umbenennt, sollte man es nicht allzu sorglos einsetzen und nur Dateien in eigenen, selbst angelegten Ordnern umbenennen. Daß EXE-Programme oder DLL-Bibliotheken umbenannt werden, verhindert das Skript von selbst.

Registry-Zugriff

Selbst die heilige Windows-Datenbank, die Registry, läßt sich durch den Scripting Host steuern. Kleine Skripte können wichtige Änderungen der Registry ohne den unbequemen Registrierungseditor und vor allem gefahrlos und bequem vornehmen. Dazu kommt das WScript.Shell-Objekt mit seinen Methoden RegRead, RegWrite und RegDelete zum Zuge.

Das Skript BENUTZER.VBS ändert die Benutzerdaten einer Windows-Installation. Wer sich zum Beispiel bei der Installation vertippt hat, kann den Fehler so im nachhinein korrigieren - andernfalls übernehmen viele Programme bei ihrer Installation immer wieder die alten Angaben aus der Registry.

Ähnlich wichtig ist das Skript SETUPDIR.VBS. Es gibt Ihnen die Freiheit, selbst zu entscheiden, wo die Windows-Installationsdateien liegen. Sobald man beispielsweise ein Laufwerk nachrüstet, kann die Installations-CD-ROM einen anderen Laufwerksbuchstaben tragen. Dann stellt Windows jedesmal, wenn Komponenten nachzuinstallieren sind, wieder das falsche Laufwerk ein. Noch praktischer wird das Skript, wenn Sie die CAB-Dateien der Windows-CD auf die lokale Festplatte kopieren, um auch später ohne Windows-CD nach- oder umkonfigurieren zu können.

Dateizuordnungen sichern ...

Viele Windows-Probleme entstehen durch die Registry: Sie regelt unter anderem, welches Programm startet, wenn man eine Datei doppelklickt. Leider übernehmen viele Programme bei ihrer Installation ungefragt die Herrschaft über Dateitypen - auch wenn man diese lieber mit einem anderen Programm öffnen würde. Wer nicht stundenlang neu installieren möchte, verwendet einfach das Skript SAVE.VBS. Es liest alle Datei-Programm-Verknüpfungen aus der Registry aus und legt für alle Dateitypen separate REG-Dateien an, aus denen man im Notfall die kompletten Zuordnungen binnen Sekunden wiederherstellen kann. Das Speichern kann je nach Windows-Installation übrigens einige Minuten dauern.

Weil der Scripting Host keine Möglichkeit enthält, die Namen von Registry-Schlüsseln abzufragen, geht das Programm einen Umweg: Es exportiert den gesamten Registry-Inhalt per REGEDIT in eine Textdatei und wertet diese aus.

Möchten Sie künftig eine zerbrochene Datei-Programm-Zuordnung reparieren oder eine veränderte rückgängig machen, würde es genügen, die passende REG-Datei aus dem Ordner C:\BACKUPS aufzurufen. Dies wäre allerdings nur eine Notlösung, denn erstens können REG-Dateien nur Einträge in die Registry hineinschreiben, aber keine vorhandenen Einträge löschen. Zweitens hätten Sie auf diese Weise keine Möglichkeit, die bestehende Datei-Programm-Zuordnung zu sichern, bevor sie durch die REG-Datei verändert würde.

... und wiederherstellen

Besser ist deshalb der Einsatz unseres Skriptes RESTORE.VBS. Es fragt nach der Dateiextension, die es reparieren soll, und bietet dann alle Sicherungskopien zur Auswahl an, die für diese Extension angelegt wurden. Falls nur eine Sicherheitskopie in Frage kommt, verzichtet es auf das Auswahlmenü.

Der Sicherheit halber speichert es die aktuelle Registry-Information als eigenständige Sicherungskopie unter einem frei wählbaren Namen, so daß man sie jederzeit und risikolos wiederherstellen kann. Damit dieses Skript das vorangegangene ansprechen kann, um die aktuelle Datei-Programm-Verknüpfung zu sichern, müssen beide Skripte im selben Ordner liegen. Vor dem Einlesen der REG-Informationen über REGEDIT löscht das Skript die vorhandenen Schlüssel und sorgt so dafür, daß die Datei-Programm-Zuordnungen exakt in der Form wiederbelebt werden, wie sie gesichert wurden.

Schriftproben drucken

Gleich eine ganze Reihe von Tricks stellt das Skript SCHRIFTEN.VBS vor, das eine Liste mit Schriftproben aller installierten Fonts ausdruckt. Weil der Scripting Host keine Funktion besitzt, um die installierten Schriftarten abzufragen, beauftragt das Skript einfach REGEDIT.EXE, den betreffenden Zweig der Registry zu exportieren. Anschließend wertet die Funktion GetFonts diese Textdatei aus und liefert ein Variablenfeld mit den Schriftnamen zurück. Da nur die Grundschriften einer Schriftfamilie angezeigt werden sollen, löscht anschließend die Prozedur Konzentrieren alle Schriften-Namen, die auf eine Familie hinweisen, also alle Schriften, die Schlüsselwörter wie beispielsweise `Italic´ oder `Fett´ enthalten. Damit die Schriftenliste auch wirklich übersichtlich ist, sortiert die Prozedur Sortieren die gefundenen Schriften anschließend nach dem Bubble-Sort-Verfahren alphabetisch. Anschließend generiert das Skript die HTML-Schriftdatei. Das Skript bietet dabei die Möglichkeit, einen eigenen Probetext festzulegen. Ohne Probetext druckt das Skript den Schrift-Namen im jeweiligen Font aus. Nebenbei demonstriert das Skript, wie HTML-Code dazu genutzt werden kann, per Skript einfach und schnell formatierte Texte auszugeben.

Postbote

Zum Schluß noch zwei mächtige Skriptanwendungen, die zeigen, wie man den WSH um zusätzliche Befehle, etwa zum Versenden von EMails, erweitert. Die Firma Persits Software [10] verschenkt freundlicherweise die Datei aspemail.zip, die alle nötigen Funktionen enthält. Extrahieren Sie die Datei AspEmail.dll aus dem ZIP-Archiv und kopieren Sie sie auf die lokale Festplatte, zum Beispiel nach C:\Windows\System\. Anschließend müssen Sie das neue ActiveX-Modul bei Windows registrieren, um die darin enthaltenen Befehle nutzen zu können. Dazu wählen Sie im Startmenü `Ausführen´ und geben ein: REGSVR32 C:\Windows\System\AspEmail.dll.

Das Skript EMAILZIP.VBS demonstriert zunächst, wie man mit Hilfe der neuen Befehle bequem ZIP-Dateien als EMail-Attachments verschicken kann - direkt vom Explorer aus, ohne speziellen EMail-Client. Passen Sie das Skript an Ihre persönlichen Verhältnisse an: `From´ steht für Ihre EMail-Adresse, `FromName´ für Ihren Namen. Unter `Host´ sollten Sie die Adresse des SMTP-Servers bei Ihrem Provider eintragen; das Skript verwendet stellvertretend den von CompuServe.

Nach dem Start fragt das Programm nach dem Namen der ZIP-Datei, die es versenden soll, nach der EMail-Adresse des Empfängers sowie nach dem Betreff (Subject) der zugehörigen Nachricht. Richtig praktisch wird das Skript allerdings erst, wenn man es ins Kontextmenü für ZIP-Dateien integriert, um Dateien per Rechtsklick versenden zu können. Dazu geht man vor wie beim Skript FEHLER.VBS, wählt als verknüpften Dateityp entsprechend ZIP-Dateien, etwa die von WinZip. Als Namen des neuen Befehls kommt beispielsweise `als Email versenden´ in Frage, als Befehlsaufruf etwa WSCRIPT.EXE C:\SCRIPTS\EMAILZIP.VBS "%L".

Serien-EMails

Das vorige Skript ist zwar recht nützlich, es kann aber kaum mehr als ein ordentliches EMail-Programm. Wohl aber das nächste: EMAILDAT.VBS verschickt Nachrichten oder Dateien quasi als EMail-Serienbrief gleich an eine ganze Reihe von Empfängern, die der Anwender in einer Datenbank wie etwa MS Access verwaltet. Voraussetzung ist freilich, daß ein taugliches Programm als Systemdatenbank angemeldet ist; das erkennen Sie daran, daß in der Systemsteuerung ein Modul namens `32bit ODBC´ existiert.

Im Register `System DSN´ legen Sie per `Add´ respektive `Hinzufügen´ den Typ der Datenbank fest, eben etwa Microsoft Access. Im Feld Datenquellenname bestimmen Sie den Namen der Datenbank, über den der Scripting Host später die Datenbank ansprechen soll, zum Beispiel `Internet´. Klicken Sie zum Schluß auf Auswählen, und stellen Sie den Pfadnamen zu Ihrer Datenbank-Datei ein, die Namen und EMail-Adressen der Empfänger enthält, bei Access also eine MDB-Datei. Falls eine solche bei Ihnen bereits existiert, brauchen Sie nur die Feldnamen im Skript anzupassen. Andernfalls legt man einfach eine neue Datenbankdatei samt passender Tabelle `Emailversand´ und mindestens einem Feld für die Adressen namens `Email´ an.

Das Skript stellt zuerst eine Verbindung zu den vier ActiveX-Komponenten her, die es für seine Arbeit braucht: Datenbank, EMail, Dateisystem und Programmausführung. Anschließend bietet es die Möglichkeit, per Editor den EMail-Nachrichtentext zu verfassen. Dazu legt das Programm per CreateTextFile eine leere Textdatei an und ruft diese per Run auf - der Editor startet automatisch. Sobald die Nachricht gespeichert ist und der Editor wieder geschlossen wird, liest das Programm den Inhalt der Datei und verwendet die erste Zeile als EMail-Subject, den Rest als Nachricht.

Nun öffnet es die Systemdatenbank `Internet´ und formuliert eine Standard-SQL-Abfrage: SELECT * FROM Emailversand, um alle Felder der Tabelle Emailversand auszuwählen. Über Execute schickt es die Anweisung an die Datenbank. Zurückgeliefert wird ein Recordset mit dem Ergebnis, welches das Programm in einer Schleife ausliest und alle EMail-Adressen über AddAddress als Empfänger vermerkt. Danach füllt es die übrigen Felder des EMail-Formulars aus und schickt die EMail ab.

Natürlich ist dieses Programm nur ein einfaches Grundgerüst. Aber es läßt sich in vielfältiger Weise ausbauen. Denkbar wäre beispielsweise ein weiteres Feld in der die Datenbank-Tabelle, etwa `Privat´, das dann als Auswahlkriterium fungiert, um den Empfängerkreis der Massensendung einzuschränken. Die SQL-Anweisung müßte dann lauten: SELECT * FROM Emailversand WHERE Privat=1.

Weitere Verbesserungsmöglichkeiten: Statt die EMail per Editor zu verfassen, könnte sie auch direkt aus der Datenbank stammen. Oder die Adressen anderer Empfänger könnten für jeden einzelnen unsichtbar werden, indem anstelle von AddAddress der Befehl AddBCC verwendet würde. Dann würden die EMails als `Blind Carbon Copy´ verschickt. Oder Sie würden alle EMails einzeln versenden. Dazu böte sich der Reset-Befehl an, der die Empfängerliste nach jedem Versand leerte. Oder ...

Forschungsstation WSH

Unsere 20 Skripte bieten also schon jede Menge Anlaß für eigene Experimente. Schreiben Sie die Skripte nach Herzenslust um und entwickeln Sie für all jene Arbeitsschritte, die sich wiederholen, ein eigenes. Wenn Ihnen die hier gelieferten Informationen nicht genügen sollten, finden Sie weitere in einem ausführlichen Buch zum Thema [8]. Entwickler versorgt Microsoft selbst mit ausführlichem Material auf seinen Developer-Seiten [9]. Viel Spaß beim Skripten!(se)

Software und Literatur
[1] Scripting Host zum Download: http://www.microsoft.com/scripting/windowshost/download/en/x86/wsh.exe

[2] Dokumentation zu VBScript: http://msdn.microsoft.com/scripting/vbscript/download/vbsdoc.exe

[3] Dokumentation zu JScript: http://msdn.microsoft.com/scripting/jscript/download/jsdoc.exe

[4] HTML-Hilfe-Update: http://msdn.microsoft.com/isapi/gomscom.asp?Target=/workshop/author/htmlhelp/download.asp

[5] VBA Companion: http://www.apexsc.com/vbacompanion/download.html

[6] Microsoft Developer Library: http://msdn.microsoft.com/library/

[7] Visual Basic Control Creation Edition: http://msdn.microsoft.com/vbasic/downloads/cce/default.asp (als Gastentwickler registrieren)

[8] Tobias Weltner: Windows 98, Kraftpaket zum Durchstarten, Franzis-Verlag, ISBN 3-7723-5864-0

[9] http://msdn.microsoft.com/scripting/

[10] http://www.aspemail.com/

[11] http://www.heise.de/ct/ftp/listings.shtml

Kasten 1


Weitere Artikel zum Scripting

Browser und JavaScript Seite 114
Word und VBA Seite 118
Corel Draw/Photo Paint und CorelScript Seite 126
Makroprogramme als Alternative Seite 134

Kasten 2


Sicherheitsloch Scripting Host?

Seit es den Windows Scripting Host gibt, machen immer wieder Meldungen über dessen Sicherheitslecks die Runde. Vorsicht ist durchaus angebracht, aber es ist nicht der WSH, der Hackern die Manipulationsmöglichkeiten in Ihrem Windows verschafft. Gefährlich wird es erst, wenn andere Programme oder sogenannte Trojanische Pferde Möglichkeiten nach außen vermitteln, das System über den WSH fernzusteuern. Genau das ist möglich, wenn der Internet Explorer als Web-Browser benutzt wird. Der gestattet es nämlich im Unterschied zu den meisten anderen Browsern, in Web-Seiten eingebettete VBScript-Programme auszuführen.

Beim Besuch solcher Seiten warnt der Internet Explorer lediglich mit einer unscheinbaren Dialogbox vor `möglicherweise unsicheren´ Inhalten. Diese Warnung sollte man nicht ignorieren, denn über diesen Schleichweg können Saboteure allen möglichen Schaden anrichten, zum Beispiel die Festplatten löschen, Paßwörter ausspionieren oder die Windows-Registry verändern.

minpic04.jpg

Vorsicht, Sicherheitslücke: ActiveX-Zugriffe sollte man dem Internet Explorer verbieten.

Selbst wenn der WSH gar nicht installiert ist, bieten solche in Internetseiten eingebetteten VBScripte die Möglichkeit, Verbindung zu ActiveX-Komponenten Ihres Systems aufzunehmen und Unheil anzurichten. Das FileSystemObject beispielsweise, mit dem das gesamte Dateisystem offengelegt wird, befindet sich auch ohne WSH in jeder Windows-Installation, die den Internet Information Server (IIS) oder den Personal Webserver verwenden. Dieses gravierende Sicherheitsproblem betrifft damit sogar das vermeintlich sichere Windows NT. Um so wichtiger ist es, diese Sabotagemöglichkeiten konsequent abzuschalten und den Internet Explorer auf Normalbrowser-Niveau zu beschränken. Dazu genügt es, in der Systemsteuerung das Internet-Modul aufzurufen und auf das Register `Sicherheit´ zu klicken. Anschließend wählen Sie die Option `Angepasst´ und klicken auf Einstellungen. Deaktivieren Sie gegebenenfalls das `Initialisieren und Ausführen von ActiveX-Steuerelementen´.

Kasten 3


MINI.VBS minimiert alle geöffneten Fenster des Desktop und maximiert sie auf Mausklick wieder.

set shell = CreateObject("Shell.Application")
shell.MinimizeAll
MsgBox "Klicken Sie auf OK, wenn Sie die Fenster zurückhaben möchten!"
shell.UndoMinimizeAll
Kasten 4

CLOSE.VBS schließt alle geöffneten Fenster.

set Shell = CreateObject("Shell.Application")

for each window in shell.windows
  set parent = window.Application
  parent.Quit
next
Kasten 5

DATUM.VBS rechnet ein beliebiges Datum in den jeweiligen Wochentag um - die zugehörige Funktion ist im Scripting Host eingebaut.

frage="Bitte geben Sie ein Datum ein, und ich verrate Ihnen den Wochentag!"
datum=InputBox(frage)
if isDate(datum) then
  antwort = "Der " & datum & " fällt auf einen "
  antwort = antwort + WeekdayName(Weekday(datum))
  MsgBox antwort, vbInformation
else
  antwort = datum & " ist kein gültiges Datum!"
  MsgBox antwort, vbExclamation
end if
Kasten 6

Ganz simpel: WINDIR.VBS ermittelt den Windows-Pfad.

set WSHShell = CreateObject("WScript.Shell")
windir = WSHShell.ExpandEnvironmentStrings("%WINDIR%")
MsgBox "Ihr Windows-Ordner lautet: " & windir
Kasten 7

LOGBUCH.VBS protokolliert, wer sich wann bei Ihrem Windows angemeldet hat.

´ legt ein Anmeldelogbuch für Windows an

set network = CreateObject("WScript.Network")       ´ für UserName
set fs = CreateObject("Scripting.FileSystemObject") ´ für Dateisystem

logbuch = "C:\anmeldung.log"  ´ Name des Logbuchs

´Logbuch im Append-Modus (8) öffnen und anlegen, falls es noch
´gar nicht existiert (vbTrue):
set logfile = fs.OpenTextFile(logbuch, 8, vbTrue)

´Protokollzeile schreiben: now=Timestamp, UserName=Anmeldename
logfile.WriteLine now & " Angemeldeter User: " & network.UserName
logfile.close
Kasten 8

FEHLER.VBS hilft bei der Fehlersuche in Skripten.

´markiert fehlerhafte Zeile in einem Skript

´ Verbindung zu System-ActiveX-Modulen herstellen
set WSHShell = CreateObject("WScript.Shell")        ´ für Run-Befehl
set fs = CreateObject("Scripting.FileSystemObject") ´ für Dateisystem
set args = WScript.Arguments                        ´ für Argumente

´wurde der Name eines Skripts übergeben?
if args.count=0 then
  datei=InputBox("Wie heißt die Skriptdatei, in der ein Fehler auftrat?")
else
  datei=args(0)
end if
if not fs.FileExists(datei) then
  MsgBox datei & " existiert nicht!", vbExclamation
  WScript.Quit
end if

zeilenr=AskNumber    ´ welche Zeile markieren?

´ Markierungsstring definieren
markierung = string(20, "x") + " FEHLERHAFTE ZEILE "
markierung = markierung + string(20, "x")

´Skriptdatei öffnen...
set einlesen = fs.OpenTextFile(datei)
ok=vbFalse
neu = ""    ´ enthält den neuen Skripttext mit Markierung
´... und zeilenweise einlesen.
do until einlesen.atEndOfStream
  if einlesen.Line = zeilenr then
    ´ angegebene Zeile gefunden: Markierung einfügen
    neu = neu + "´" + markierung + vbNewLine
    neu = neu +  einlesen.ReadLine +  vbNewLine
    neu = neu + "´" + markierung + vbNewLine
    ok=vbTrue  ´ Zeile wirklich gefunden!
  else
    ´ normale Zeile: falls alte Markierung, entfernen
    gelesen = einlesen.ReadLine
    if len(gelesen)=len(markierung)+1 then
      if not gelesen="´" + markierung then
        neu = neu + gelesen + vbNewLine
      end if
    else
      neu = neu + gelesen + vbNewLine
    end if
  end if
loop
einlesen.close

if not ok and not zeilenr=0 then
  ´ angegebene Zeilennummer existiert nicht!
  MsgBox "Zeile " & zeilenr & " gibt es im Programm nicht!", vbExclamation
  WScript.Quit
end if

´ Skriptdatei löschen und mit neuem Inhalt erneut schreiben
set einlesen = fs.CreateTextFile(datei, vbTrue)
einlesen.Write neu
einlesen.close

´ falls Zeilen-Nr=0, dann nur alte Markierungen entfernen und Meldung
if zeilenr=0 then
  MsgBox "Zeilenmarkierungen wurden aus Skript entfernt!", vbInformation
else
  ´ ansonsten das Skript im Editor öffnen:
  WSHShell.Run "NOTEPAD.EXE " + datei
end if

function AskNumber
  ´fragt nach einer Zahl größer/gleich 0
  AskNumber=-1
  do while AskNumber
Kasten 9

STARTBILD.VBS bringt Abwechslung in den tristen Windows-Alltag.

´ aktiviert in zufälliger Reihenfolge neue Startbilder

´ Verbindung zu Dateisystembefehlen herstellen
set fs = CreateObject("Scripting.FileSystemObject")

bildarchiv = "C:\bilder"  ´ hier lagern die Startbilder

if not fs.FolderExists(bildarchiv) then
  ´ Ordner mit Startbildern existiert nicht!
  problem = bildarchiv + " existiert nicht. Legen Sie den Ordner an,"
  problem = problem + "und speichern Sie darin Windows-Startbilder!"
  MsgBox problem, vbExclamation
  WScript.Quit
end if

set startbilder = fs.GetFolder(bildarchiv).files
´ Anzahl der vorhandenen Startbilder bestimmen:
for each bild in startbilder
  anzahl = anzahl + 1
next

if anzahl=0 then
  ´ gar keine Startbilder zu finden!
  problem=bildarchiv+" ist leer. Speichern Sie darin zuerst Startbilder!"
  MsgBox problem, vbExclamation
  WScript.Quit
end if

´ neues Startbild per Zufall aussuchen
zufallszahl = Zufall(1, anzahl)

´ dieses Bild heraussuchen
for each bild in startbilder
  zufallszahl = zufallszahl - 1
  if zufallszahl = 0 then
    ´ gefunden! Altes Startbild löschen, falls vorhanden
    if fs.FileExists("C:\LOGO.SYS") then
      fs.DeleteFile "C:\LOGO.SYS", vbTrue
    end if

    ´ neues Startbild aktivieren
    bild.Copy "C:\LOGO.SYS", vbTrue
    ´ Die nächste Zeile löschen, wenn Meldung stört!
    MsgBox bild.name & " wurde aktiviert!"
    exit for
  end if
next

function Zufall(min, max)
  ´ liefert eine Zufallszahl zwischen min und max
  randomize
  Zufall = Int(max * rnd) + min
end function
Kasten 10

Sonderzeichen und deutsche Umlaute konvertieren von Windows nach DOS oder Macintosh mit KONVERT.VBS.

´ konvertiert Textdateien von DOS-ASCII nach WIN-ANSI

´Verbindung mit Systemkomponenten aufnehmen
set dialog = CreateObject("MSComDlg.CommonDialog")´Öffnen/Speichern-Dialog
set fs = CreateObject("Scripting.FileSystemObject")  ´Dateisystem

´Dialogfenster definieren
dialog.Filter = "Alle Dateien (*.*)|*.*|txt-Dateien|*.txt|"
dialog.FilterIndex = 2       ´ zweiter Filter (txt-Dateien) vorgewählt
dialog.MaxFileSize = 250     ´ max. Dateinamen-Länge im Buffer
dialog.CancelError = vbFalse ´ Abbrechen-Schaltfläche liefert Leerstring
dialog.DialogTitle = "Zu konvertierende Datei aussuchen"
dialog.InitDir = "C:\"
dialog.ShowOpen

dateiname = dialog.FileName
if fs.FileExists(dateiname) then
  ´ Originaldatei einlesen
  MsgBox "Konversion kann je nach Dateigröße einige Minuten dauern!", _
    vbInformation
  set datei = fs.OpenTextFile(dateiname)
  text = datei.ReadAll
  datei.close
  
  ´ Konversion der deutschen Umlaute
  text = Replace(text, chr(148), chr(246))  ´ö
  text = Replace(text, chr(132), chr(228))  ´ä
  text = Replace(text, chr(129), chr(252))  ´ü
  text = Replace(text, chr(153), chr(214))  ´Ö
  text = Replace(text, chr(142), chr(196))  ´Ä
  text = Replace(text, chr(154), chr(220))  ´Ü
  text = Replace(text, chr(225), chr(223))  ´ß

  ´ Zieldatei erfragen
  dialog.DialogTitle = "Konvertierte Datei speichern als"
  dialog.FileName = left(dateiname,InstrRev(dateiname,".")-1)+"_ANSI.txt"
  dialog.ShowSave
  dateiname = dialog.FileName
  if dateiname="" then
    MsgBox "Abbruch!", vbExclamation
  else
    ´ Konvertierten Text in Zieldatei schreiben
    set datei = fs.CreateTextFile(dateiname, vbTrue)
    datei.Write text
    datei.close
    MsgBox "Konvertierung beendet!", vbInformation
  end if
else
  MsgBox "Abbruch!", vbExclamation
end if
Kasten 11

Was dem Explorer fehlt, rüstet DRUCKEN.VBS nach: die Möglichkeit, Dateilisten auszudrucken.

´druckt ein Ordnerlisting aus

´Zugriff auf ActiveX-Komponenten des Systems herstellen
set WSHShell = CreateObject("WScript.Shell")        ´ nötig für Run-Befehl
set fs = CreateObject("Scripting.FileSystemObject") ´ Dateisystembefehle
set args = WScript.Arguments                        ´ übergebene Argumente

if args.Count=0 then
  ´keine Argumente übergeben? Dann Ordnernamen angeben!
  ordner = InputBox(_
           "Geben Sie den Ordner an, dessen Inhalt gedruckt werden soll!")
else
  ´ansonsten übergebenen Ordnernamen benutzen
  ordner = args(0)
end if

´enthält das Ordnerlisting:
tempdatei = "C:\TMP.TXT"

´per DOS-Befehl Ordner ausdrucken
WSHShell.Run "command.com /c dir /on /og " + chr(34) + ordner + chr(34) _
  + " > " + tempdatei, 0, vbTrue

´erfolgreich? Dann Datei lesen und ASCII-Umlaute in ANSI-Zeichen wandeln
if fs.FileExists(tempdatei) then
  ´ Datei öffnen und komplett lesen
  set eingabe = fs.OpenTextFile(tempdatei)
  text = eingabe.ReadAll
  eingabe.close

  ´ ASCII-Zeichen ersetzen
  text = Replace(text, chr(148), chr(246))
  text = Replace(text, chr(132), chr(228))
  text = Replace(text, chr(129), chr(252))
  text = Replace(text, chr(153), chr(214))
  text = Replace(text, chr(142), chr(196))
  text = Replace(text, chr(154), chr(220))
  text = Replace(text, chr(225), chr(223))

  ´ Datei mit konvertiertem Inhalt neu schreiben
  set ausgabe = fs.CreateTextFile(tempdatei, vbTrue)
  ausgabe.Write text
  ausgabe.close

  ´ Datei ausführen (startet automatisch Notepad)
  WSHShell.Run tempdatei
end if
Kasten 12

MSDOSSYS.VBS ermöglicht das direkte Editieren von geschützten und versteckten Systemdateien.

´ Demonstriert Dateiattribute am Beispiel von MSDOS.SYS:
´ Datei wird zur Bearbeitung freigegeben und im Notepad angezeigt,
´ sobald Notepad geschlossen wird, stellt Skript die Attribute wieder her

´ Zugriff auf Systemkomponenten herstellen
set fs = CreateObject("Scripting.FileSystemObject") ´ Dateisystem
set WSHShell = CreateObject("WScript.Shell")        ´ Run-Befehl

dateiname = "C:\MSDOS.SYS"

Unlock dateiname  ´ Schutzattribute aufheben, dann Datei öffnen
WSHShell.Run "NOTEPAD " + dateiname, ,vbTrue
Lock dateiname    ´ Schutzattribute wiederherstellen

MsgBox dateiname & " ist wieder schreibgeschützt und versteckt.", _
  vbInformation

sub Unlock(datei)
  ´entfernt die Attribute Schreibschutz/Versteckt/System
  if not fs.FileExists(datei) then
    MsgBox datei + " existiert nicht.", vbCritical
    WScript.Quit
  else
    set handle = fs.GetFile(datei)
    ´ 1=schreibgeschützt, 2=versteckt, 4=System, 32=Archiv
    handle.attributes = handle.attributes and not (1+2+4+8+16+64+128)
  end if
end sub

sub Lock(datei)
  ´setzt die Attribute wieder
  if not fs.FileExists(datei) then
    MsgBox datei + " existiert nicht.", vbCritical
    WScript.Quit
  else
    set handle = fs.GetFile(datei)
    ´ Bits 8+16+64+128 müssen vor dem Setzen gelöscht werden, weil
    ´ diese Bits readonly sind und bei Schreibversuch zum Fehler führen
    handle.attributes = handle.attributes and not (8+16+64+128) or (1+2+4)
  end if
end sub
Kasten 13

DOKU.VBS reinigt das überladene Dokumente-Menü von Windows.

´ Löscht alle Einträge aus dem Dokumente-Menü, die nicht auf
´ Dateien der folgenden Typen verweisen:

´Zugriff auf ActiveX-Objekte des Systems 
set fs = CreateObject("Scripting.FileSystemObject")
Set WshShell = Wscript.CreateObject("Wscript.Shell")

´ Erwünschte Dateiextensionen festlegen
erlaubt = "doc;txt;bmp;html;htm"
erlaubt = split(erlaubt, ";")  ´ Variablenfeld mit Extensionen

´ Ordnername des Dokumente-Menüs herausfinden
set dokumenu = fs.GetFolder(WshShell.SpecialFolders("Recent"))

´ Alle Dateien im Dokumente-Menü untersuchen...
set dokumente = dokumenu.files
for each link in dokumente
  ´... ist die Datei eine Verknüpfung? Extension = LNK?
  if lcase(fs.GetExtensionName(link.name)) = "lnk" then
    ´ ja: Verknüpfungsobjekt anlegen, um an Details zu kommen
    set linkobj = WshShell.CreateShortcut(link.path)
    ´ wie lautet die Extension der Zieldatei dieser Verknüpfung?
    extension = lcase(fs.GetExtensionName(linkobj.TargetPath))

    ´ ist die Extension eine der "erwünschten" Extensionen?
    behalten = vbfalse
    for check = 0 to ubound(erlaubt)
      if extension = lcase(erlaubt(check)) then
        behalten=vbtrue
        exit for
      end if
    next
    if not behalten then
      ´ nein: also Verknüpfung aus Dokumente-Menü löschen
      link.delete vbtrue
    end if     
  end if
next
Kasten 14

Individuelle Ordner-Icons unter Windows erlaubt ICONS.VBS.

´ Individuelle Ordnericons (für Win98/IE4)

´ Zugang zu Systemkomponenten herstellen
set args = Wscript.Arguments                        ´ übergebene Argumente
set WSHShell = CreateObject("WScript.Shell")        ´ für Run-Befehl
set fs = CreateObject("Scripting.FileSystemObject") ´ Dateisystem-Befehle

if args.Count=0 then
  ordnername = InputBox("Geben Sie den Pfadnamen des Ordners ein, " _
    & "dem Sie ein neues Icon geben möchten!")
else
  ordnername = args(0)
end if

´ Windows-Ordner ermitteln
win = WSHShell.ExpandEnvironmentStrings("%WINDIR%") + "\"
frage1 = "Wie heißt der Pfadname der Icon-Bibliothek?"
frage2 = "Wie lautet die Kennzahl des Icons?"
iconfile = InputBox(frage1,,win + "PROGMAN.EXE")
iconnumber = InputBox(frage2,,0)

´ speziell angepaßte DESKTOP.INI generieren und in Ordner legen
OrdnerIcon ordnername, iconfile, iconnumber  

sub OrdnerIcon(ordner, icon, nr)
  ´existiert der Ordner überhaupt?
  if not fs.FolderExists(ordner) then
    MsgBox ordner & " existiert nicht.", vbExclamation
    exit sub
  end if

  ´ DESKTOP.INI-Datei für den Ordner anlegen  
  ini = ordner + "\desktop.ini"
  set ausgabe = fs.CreateTextFile(ini, vbTrue)

  ´ Icon-Informationen in DESKTOP.INI schreiben:
  ausgabe.WriteLine "[.ShellClassInfo]"
  ausgabe.WriteLine "IconFile=" + iconfile
  ausgabe.WriteLine "IconIndex=" + iconnumber
  ausgabe.close

  ´ Attribute des Ordners setzen
  set ordner = fs.GetFolder(ordner)
  attribute = ordner.Attributes
  attributeoff = attribute and not (4+8+16+64+128)
  attributeon = attribute and not (8+16+64+128) or 4
  ordner.attributes = attributeoff
  info = "Neue Icons werden erst nach Aktualisierung des Explorers sichtbar." _
    + vbCr + "Dazu bitte eine freie Stelle des Desktops anklicken und dann" _
    + vbCr + "auf [F5] drücken."
  MsgBox info, vbInformation
  ordner.attributes = attributeon
end sub
Kasten 15

UMBENENNEN.VBS schafft Ordnung im Dateichaos und vergibt einheitliche Seriennummern.

´ersetzt die Dateinamen eines bestimmten Dateityps innerhalb eines Ordners
´durch fortlaufende Seriennummern

´Variablen zwingend deklarieren, um Tippfehler zu vermeiden
option explicit

dim dateiliste(10000) ´Liste der gefundenen zutreffenden Dateinamen
dim fs           ´ Referenz zum FileSystemObject
dim frage        ´ Fragen an den Benutzer
dim ordner       ´ Dateiordner, der die Dateien enthält
dim prefix       ´ Zeichenfolge, die vor der Seriennummer eingefügt wird
dim ext          ´ Extension (Dateityp), der gesucht werden soll
dim counter      ´ Anzahl gefundener Dateien des gewünschten Dateityps
dim ordnerhandle ´ Handle auf den Ordner, der die Dateien enthält
dim ordnername   ´ genauer Pfadname des Ordners
dim datei        ´ Handle der Dateien im Ordner
dim dateiname    ´ Name der untersuchten Datei, ohne Pfad und Extension
dim extension    ´ Extension der untersuchten Datei (Dateityp)
dim antwort      ´ Antwort des Benutzers auf Abfragen
dim zaehler      ´ laufende Seriennummer
dim schleife     ´ Schleifenvariable
dim digits       ´ Anzahl der Stellen für die Seriennummer
dim modus        ´ 1=Dateiname in Kleinbuchstaben, 2=in Großbuchstaben

counter = 0
digits = 4
modus = 2

´Zugriff auf ActiveX-Objekte des Systems herstellen
set fs = CreateObject("Scripting.FileSystemObject")

´ Angaben zur Konversion erfragen
frage = "Welcher Ordner soll bearbeitet werden?"
ordner = IB(frage, "Ordner", "C:\")

´ Existiert der angegebene Ordner überhaupt?
if not fs.FolderExists(ordner) then
  MsgBox "Der Ordner " & ordner & " existiert nicht! Abbruch!", _
    vbExclamation
  WScript.Quit
end if

frage = "Wie heißt die Dateiextension des Dateityps, den Sie " _
  & "berücksichtigen wollen?"
ext = replace(lcase(IB(frage, "Extension", "jpg")), ".", "")

frage = "Bitte geben Sie das Prefix an, das als Dateiname verwendet " _
  & "werden soll!"
prefix = InputBox(frage, "Prefix", "datei")

´System-Dateitypen schützen
if ext="exe" or ext="dll" or ext="sys" or ext="vxd" then
  MsgBox "Der Dateityp " & ext _
    & " darf auf keinen Fall umbenannt werden!", vbCritical
  WScript.Quit
end if


´ Ordner mit den Dateien öffnen
set ordnerhandle = fs.GetFolder(ordner)
ordnername = ordnerhandle.path

´ Jede Datei im Ordner untersuchen
for each datei in ordnerhandle.files
  dateiname = fs.GetBaseName(datei.Name)
  extension = lcase(fs.GetExtensionName(datei.Name))
  
  ´ richtiger Dateityp?
  if extension = ext then
    ´ noch kein Prefix zugeordnet?
    if not lcase(left(dateiname, len(prefix))) = lcase(prefix) _
        or prefix="" then
      counter = counter + 1
      dateiliste(counter) = datei.path
    end if
  end if
next

´Ergebnis präsentieren
frage = "Es wurden " & counter & " zutreffende " & ext _
    & "-Dateien gefunden." + vbCr
if counter = 0 then
  frage = frage + "Das Programm bricht ab!"
  MsgBox frage, vbInformation
  WScript.Quit
else
  frage = frage+"Wollen Sie die Dateinamen durch Seriennummern ersetzen?"
end if

´Soll wirklich konvertiert werden?
antwort = MsgBox(frage, vbYesNo + vbQuestion)
if antwort = vbYes then
  zaehler = 0
  for schleife = 1 to counter
    dateiname = prefix & format(zaehler) & "." & ext
    do while fs.FileExists(ordnername + "\" + dateiname)
      zaehler = zaehler + 1
      dateiname = prefix & format(zaehler) & "." & ext        
    loop
    set datei = fs.GetFile(dateiliste(schleife))
    if modus=1 then
      dateiname = lcase(dateiname)
    elseif modus=2 then
      dateiname = ucase(dateiname)
    end if
    datei.name = dateiname
    zaehler = zaehler + 1
  next
  MsgBox "Erledigt!", vbInformation
else
  MsgBox "Abbruch!", vbExclamation
end if

function IB(a, b, c)
  ´ entspricht der InputBox-Funktion, berücksichtigt aber die
  ´ Abbruch-Schaltfläche
  IB = InputBox(a, b, c)
  if IB="" then
    MsgBox "Abbruch!", vbInformation
    WScript.Quit
  end if
end function

function format(zahl)
  ´ formatiert eine Zahl durch vorangestellte "0" und erweitert die Zahl
  ´ auf diese Weise auf die in der Variablen digits festgelegten Stellen

  format = string(digits-len(cstr(zahl)), "0") & zahl
end function
Kasten 16

Benutzer.VBS ändert auch im nachhinein noch die Benutzerdaten.

´ nachträglich Benutzernamen und Firma in der Registry ändern

´ ActiveX-Zugriff für Registry-Funktionen herstellen
set WSHShell = CreateObject("WScript.Shell")

key = "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion"
userkey = key + "\RegisteredOwner"
firmakey = key + "\RegisteredOrganization"

benutzer = InputBox("Benutzernamen ändern?", "Benutzer", _
  WSHShell.RegRead(userkey))
firma = InputBox("Firmennamen ändern?", "Firma", _
  WSHShell.RegRead(firmakey))
WSHShell.RegWrite userkey, benutzer
WSHShell.RegWrite firmakey, firma
antwort = MsgBox("Wollen Sie die Änderungen sofort kontrollieren?", _
  vbYesNo + vbQuestion)
if antwort = vbYes then WSHShell.Run "CONTROL.EXE sysdm.cpl"

minpic02.jpg

Wer sich bei der Windows-Installation vertippt hat, kann den eingetragenen Benutzernamen später nicht mehr ändern. Dank Skript klappt´s doch.

Kasten 17


SETUPDIR:VBS: Windows muß nicht immer in C:\Windows liegen ...

set WSHShell = CreateObject("WScript.Shell")

key = "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\" _
  + "Setup\SourcePath"
frage = "Windows-Installationsverzeichnis ändern?"
aktuell = WSHShell.RegRead(key)

neu = InputBox(frage,"Installationsverzeichnis", aktuell)
if neu="" then
  MsgBox "Abbruch!", vbExclamation
else
  WSHShell.RegWrite key, neu
  MsgBox "Aktuelles Installationsverzeichnis:" + vbCr + neu, vbInformation
end if
Kasten 18

SAVE.VBS speichert Dateiverknüpfungen, die Programme gerne mal überschreiben.

set WSHShell = CreateObject("WScript.Shell")
set fs = CreateObject("Scripting.FileSystemObject")
set args = WScript.Arguments

dir = "C:\backups"  ´hier werden die Backups gelagert
if not fs.FolderExists(dir) then fs.CreateFolder(dir)

if args.count=0 then
  ´ Keine speziellen Argumente: also alle Dateiverknüpfungen sichern
  MsgBox "Lege Backups der Verknüpfungen an. " _
    & "Das kann einige Minuten dauern!", vbInformation
  extensionen = ReadTypes
  for each dateityp in extensionen
    BackItup dateityp, 0
  next
else
  ´ nur die angegebene Dateiverknüpfung sichern
  BackItup(args(0)), 1
end if


sub BackItup(ext, modus)
  ´sichert die angegebene Dateiverknüpfung als REG-Datei
  if not CheckKey("HKCR\" + ext + "\") then
    MsgBox "Der Schlüssel " & ext & " ist unbekannt!", vbExclamation
    exit sub
  end if

  on error resume next
  ´Dateiname für die Sicherheitskopie generieren
  timeStamp = date() & " " & replace(Time(),":","-") & " Uhr"
  name = Replace(ext,".","") + " vom " + timeStamp
  if modus=1 then name = _
    InputBox("Geben Sie der Sicherheitskopie einen Namen!", "Name", name)
  regname = dir + "\" + name + ".reg"

  ´Informationen aus der Registry exportieren
  befehl = "REGEDIT.EXE /E " + chr(34) + regname + chr(34) _
    + " HKEY_CLASSES_ROOT\" + ext 
  WSHShell.Run befehl,0,vbTrue

  ´Programmschlüssel erfragen...
  prog = WSHShell.RegRead("HKCR\" + ext + "\")
  ´... und sichern, falls er existiert:
  if (not prog="") and checkKey("HKCR\" + prog + "\") then
    temp = "C:\tmp.txt"
    befehl = "REGEDIT.EXE /E " + temp + " " + chr(34) _
      + "HKEY_CLASSES_ROOT\" + prog + chr(34)   
    WSHShell.Run befehl,0,vbTrue

    ´aus den beiden separaten REG-Dateien eine kombinierte Datei erstellen
    set dateireg = fs.OpenTextFile(regname, 8)
    set progreg = fs.OpenTextFile(temp)
    progreg.SkipLine
    progreg.SkipLine  
    do until progreg.atEndOfStream
      dateireg.WriteLine progreg.ReadLine
    loop
    dateireg.close
    progreg.close
    fs.DeleteFile temp
  end if
end sub

function CheckKey(key)
  ´prüft, ob ein Schlüssel in der Registry existiert
  on error resume next
  vorhanden = WSHShell.RegRead(key)
  if err0 then
    err.clear
    CheckKey=vbFalse
  else
    CheckKey= vbTrue
  end if
end function

function ReadTypes
  ´liest alle Dateitypen aus der Registry aus
  regexport = "C:\HKCR.HID"
  WSHShell.Run "REGEDIT.EXE /E "+regexport+" HKEY_CLASSES_ROOT", 0, vbTrue
´_________________________________________________________________________
  set eingabe = fs.OpenTextFile(regexport)
´_________________________________________________________________________
  do until eingabe.atEndOfStream
    gelesen = eingabe.ReadLine
    if len(gelesen)>20 then
      if left(gelesen,20) = "[HKEY_CLASSES_ROOT\." then
        gelesen = mid(gelesen, 20)
        if Instr(gelesen, "\")=0 then
          gelesen = left(gelesen, len(gelesen)-1)
          ext = ext + gelesen + ";"
        end if
      end if
    end if
  loop
  eingabe.close
  fs.DeleteFile regexport, vbTrue
  ext = left(ext, len(ext)-1)
  ReadTypes = Split(ext, ";")
end function
Kasten 19

RESTORE.VBS restauriert die von SAVE.VBS gespeicherten Dateiverknüpfungen.

set fs = CreateObject("Scripting.FileSystemObject")
set WSHShell = CreateObject("WScript.Shell")

dir = "C:\backups"

ext = InputBox("Wie lautet die Extension der Datei, " _
  + "die Sie wiederherstellen wollen?", "Extension")
ext = lcase(Replace(ext, ".", ""))

optionen = FindeBackups(dir)
antwort = MsgBox("Möchten Sie die aktuelle Verknüpfung sichern?", _
  vbQuestion + vbYesNo)
if antwort = vbYes then
  ordner=left(WScript.ScriptFullName,inStrRev(WScript.ScriptFullName,"\"))
  WSHShell.Run ordner + "save.vbs ." + ext, , vbTrue
end if

subkey = WSHShell.RegRead("HKCR\." + ext + "\")
wshShell.RegDelete("HKCR\." + ext + "\")
wshShell.RegDelete("HKCR\" + subkey + "\")
wshshell.Run "REGEDIT.EXE /S " + chr(34) + optionen + chr(34), 0, vbTrue
MsgBox "Alte Zuordnung ist wiederhergestellt!"

function FindeBackups(verzeichnis)
  set backups = fs.GetFolder(verzeichnis)
  resultat = ""
  optionen = "Diese Backups stehen zur Verfügung: " + vbCr
  zaehler = 0

  for each backup in backups.files
    extbackup = lcase(left(backup.Name, len(ext)))
    if extbackup + " vom" = ext + " vom"  then
      zaehler = zaehler + 1
      resultat = resultat + backup.path + ";"
      optionen = optionen + "[" & zaehler & "] " _
        + fs.GetBaseName(backup.Name) + vbCr
    end if
  next

  if len(resultat)>0 then resultat = left(resultat, len(resultat)-1)
  dateinamen = Split(resultat, ";")

  if zaehler=0 then
    MsgBox "Keine Backups gefunden!", vbExclamation
    WScript.Quit
  elseif zaehler=1 then
    FindeBackups = dateinamen(0)
  else    
    optionen = optionen + "Bitte wählen Sie eine Option aus!"
    FindeBackups = _
      dateinamen(IB(optionen, "Bitte auswählen!", "1", 1, zaehler)-1)
  end if
end function

  
function IB(a, b, c, d, e)
  ´ liefert eine Zahl zwischen d und e zurück
  do while eingabe<d or eingabe>e
    if assist then MsgBox "Ihre Antwort muß zwischen " & d _
      & " und " & e & " liegen!", vbInformation
    assist = vbTrue
    antwort = InputBox(a,b,c)
    if antwort="" then
      MsgBox "Abbruch!", vbExclamation
      WScript.Quit
    end if
    if isNumeric(antwort) then eingabe=CInt(antwort)
  loop
  IB = eingabe
end function

minpic03.jpg

Wenn die Verknüpfungen zwischen Dateien und Programmen in der Registry verlorengehen, hilft meist nur noch die Neuinstallation von Windows. In Zukunft können Sie die Einträge bequem sichern und jederzeit wiederherstellen.

Kasten 20


Wie sehen nur all die 190 installierten Schriften aus?

´ gibt Schriftprobe der installierten Schriften aus

´Kontakt zu ActiveX-Komponenten herstellen
set WSHShell = CreateObject("WScript.Shell")        ´ für Run-Befehl
set fs = CreateObject("Scripting.FileSystemObject") ´ für Dateisystem

schriftarten = GetFonts ´liefert Liste der installierten Schriften
Konzentrieren           ´entfernt Schriftfamilien
Sortieren               ´sortiert alphabetisch
Schriftprobe            ´generiert die HTML-Schriftprobe

sub Sortieren
  Melde "Sortiere Schriften..."
  for x=0 to ubound(schriftarten) 
    for y=x to ubound(schriftarten)
      if schriftarten(x)>schriftarten(y) then
        temp = schriftarten(x)
        schriftarten(x) = schriftarten(y)
        schriftarten(y) = temp
      end if
    next
  next
end sub

sub Konzentrieren
  Melde "konzentriere auf Schriftschnitte..."
  ´ Schriftfamilien-Attribute, die ausgeblendet sein sollen:
  familien = "extra bold,bolditalic,italic,bold,light,fett,kursiv," _
    & "oblique,normal"
  familien = Split(familien,",")

  for x=0 to ubound(schriftarten)
    for y=0 to ubound(familien)
      if Instr(lcase(schriftarten(x)), familien(y))>0 then
        ´ überflüssige Font-Familie: löschen!
        schriftarten(x)=""
        exit for
      end if
    next
  next
end sub

sub Schriftprobe
  Melde "Schriftprobe generieren..."
  probe = "C:\schriften.htm"
  probetext = InputBox("Bitte Probetext eingeben!", "Probetext", _
    "ABCDabcdÄÖÜäöüß 1234 Schriftprobe")
  probesize = InputBox("Bitte Schriftgröße der Probe festlegen!", _
    "Größe", "25")
  if isNumeric(probesize) then
    ´ gültige Größenangabe eingegeben
    probesize = CInt(probesize)
  else
    ´ Vorgabe verwenden
    probesize=25
  end if

  set ausgabe = fs.CreateTextFile(probe, vbTrue)
  for each schrift in schriftarten
    if schrift<>"" then
      if probetext="" then
        zusatztext = schrift
      else
        Print ausgabe, "Schriftart " + schrift + "<BR>"
      end if
      probezeile = "<p style=" + chr(34) + "font-family: " + schrift _
        + "; font-size: " & probesize & "pt" + chr(34) + ">" _
        + probetext + zusatztext + "</p><hr>"
      Print ausgabe, probezeile
    end if
  next
  WSHShell.Run probe
end sub

function GetFonts
  Melde "Stelle Schriften aus der Registry zusammen. Geduld..."
  ´ Schriftenliste aus der Registry auslesen
  tempdatei = "C:\SCHRIFT.TXT"
  key=" HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Fonts"
  WSHShell.Run "REGEDIT.EXE /E " + tempdatei + key, 0, vbTrue

  ´ Schriftenliste auswerten
  set eingabe = fs.OpenTextFile(tempdatei)
  do until eingabe.atEndOfStream
    gelesen = eingabe.ReadLine
    if len(gelesen)>1 then
      if left(gelesen,1) = chr(34) then
        ´ Zeile enthält eine Schrift...
        schrift = Split(gelesen, "=")
        name = replace(schrift(0),chr(34), "")
        position = InStr(name, "(")

        ´ Schrifttyp feststellen...
        if position>0 then
          typ = mid(name, position+1)
          typ = lcase(left(typ, len(typ)-1))
          name = left(name, position-1)
        else
          typ="truetype"
        end if

        if typ="truetype" then
          GetFonts = GetFonts + name + ";"
        end if
      end if
    end if
  loop
  eingabe.close
  fs.DeleteFile tempdatei, vbTrue

  GetFonts = Split(left(GetFonts, len(GetFonts)-1), ";")
end function

function Melde(was)
  ´ Meldung für 1 Sekunde anzeigen:
  WSHShell.Popup was, 1
end function

sub Print(obj, txt)
  obj.WriteLine txt + "<BR>"
end sub
Kasten 21

EMAILZIP.VBS verschickt ZIP-Dateien per EMail - bequem vom Kontextmenü aus.

´ ZIP-Dateien per Rechtsklick versenden

´ Zugriff auf ActiveX-Module
set fs = CreateObject("Scripting.FileSystemObject") ´Dateisystem
Set Mail = CreateObject("Persits.MailSender")       ´Email-Versand
Set args = WScript.Arguments                        ´übergebene Argumente

´ wurden Argumente übergeben?
if args.count=0 then
  ´ nein, also nach ZIP-Dateinamen fragen
  frage = "Geben Sie den kompletten Pfadnamen Ihrer ZIP-Datei an!"
  zipdatei = InputBox(frage, "Pfadname")
  
  ´ existiert die angegebene Datei überhaupt?
  if not fs.FileExists(zipdatei) then
    MsgBox zipdatei&" existiert nicht oder ist keine Datei!",vbExclamation
    WScript.Quit
  end if
else
  ´ ja, also ZIP-Dateinamen aus dem Argument benutzen
  zipdatei = args(0)
end if

´ Individuelle Email-Einstellungen:
Mail.Host = "smtp.site1.csi.com"   ´ SMTP-Mailserver
Mail.From = "anonym@anonym.net"    ´ Email-Absender
Mail.FromName = "anonym"           ´ Absender-Name

´ Adressinformationen abfragen
frage = "Geben Sie die Empfänger-Email-Adresse ein!"
email = InputBox(frage, "Empfänger")
Mail.AddAddress email
frage = "Geben Sie eine Überschrift für Ihre Email-Sendung an!"
Mail.Subject = InputBox(frage, "Überschrift")
Mail.AddAttachment zipdatei

On Error Resume Next  ´ Fehler beim Versenden abfangen
Mail.Send             ´ Email absenden
If Err  0 Then      ´ Fehler! Ursache ausgeben
  meldung = "Email konnte nicht versendet werden: " & Err.Description
  MsgBox meldung, vbExclamation
else
  meldung = "Die Datei "+ fs.GetBaseName(zipdatei) + " wurde abgeschickt!"
  MsgBox meldung, vbInformation
end if

minpic08.jpg

Schnell mal eben eine ZIP-Datei als EMail-Attachment verschicken, ohne das EMail-Programm zu starten: Mit einer DLL aus dem Internet lernt der Scripting Host auch das.

Kasten 22


Eine EMail an alle Adressen einer Datenbank verteilt EMAILDAT.VBS.

´ automatischer Email-Massenversand aus Datenbank

´ Zugriff auf ActiveX-Objekte des Systems
set db = CreateObject("ADODB.Connection")           ´ Datenbank
Set Mail = CreateObject("Persits.MailSender")       ´ Email-Versand
set fs = CreateObject("Scripting.FileSystemObject") ´ Dateisystem
set WSHShell = CreateObject("WScript.Shell")        ´ Run-Befehl

tempdatei = "C:\TEMPEMAIL"   ´ Email-Nachricht

´ neue leere Email-Datei anlegen:
set emaildatei = fs.CreateTextFile(tempdatei, vbTrue)
emaildatei.close

´ Email-Nachricht verfassen:
hinweis = "Bitte verfassen Sie Ihre Email und speichern Sie sie ab! " _
  & "Danach beenden Sie den Editor!"
MsgBox hinweis, vbInformation
WSHShell.Run "NOTEPAD.EXE " + tempdatei, , vbTrue
if not fs.FileExists(tempdatei) then
  MsgBox "Sie haben keine Email gespeichert!", vbExclamation
  WScript.Quit
end if

´ Email-Datei einlesen
set emaildatei = fs.OpenTextFile(tempdatei)
on error resume next         ´ Fehler beim Lesen abfangen
header = emaildatei.ReadLine ´ erste Zeile der Email wird zum Header
body = emaildatei.ReadAll    ´ Rest wird zur Nachricht
emaildatei.close             ´ Datei schließen und löschen
fs.DeleteFile tempdatei, vbTrue

´ Fehler beim Einlesen der Email
if err<>0 then
  hinweis = "Emaildatei konnte nicht gelesen werden und war vielleicht " _
    & "leer oder enthielt weniger als 2 Zeilen!"
  MsgBox hinweis, vbExclamation
  WScript.Quit
end if

´ Empfängeradressen aus der Datenbank lesen
db.Open "internet"       ´ Datenbank "Internet" öffnen
´ SQL-Abfrage: gesamte Tabelle "Emailversand" wählen
sql = "SELECT * FROM Emailversand"
set rs = db.Execute(sql) ´ und an die Datenbank schicken

Mail.Host = "smtp.site1.csi.com" ´ SMTP-Server festlegen
Mail.From = "anonym@anonym.net"  ´ Absender-Informationen
Mail.FromName = "MeinName"

´ Feld Email aus der Tabelle auslesen
do while testRS(RS)          ´ lesen, bis Ende der Tabelle erreicht
  email = RS("Email")        ´ Feld "Email" auslesen
  if Instr(email, "@")>0 then  ´ korrekte Email-Adresse?
    Mail.AddAddress email      ´ als weitere Empfängeradresse festlegen
  else
    hinweis = email&" ist keine gültige Email-Adresse und wird ignoriert!"
    MsgBox hinweis, vbInformation
  end if
  RS.MoveNext  ´ nächster Datensatz
loop

Mail.Subject = header  ´ Emailheader und -text festlegen
Mail.Body = body

´ Fehler beim Versenden abfangen  
On Error Resume Next    
Mail.Send          ´ Email absenden
If Err <> 0 Then   ´ Fehler! Grund angeben
  hinweis = "Fehler beim Versand: " & Err.Description
  MsgBox hinweis, vbExclamation
else
  MsgBox "Nachricht wurde versandt!", vbInformation
end if

Function testRS(RS)
  ´ prüft, ob letzter Datensatz erreicht ist
  On Error Resume Next
  bEOF = RS.EOF
  If Err Or bEOF Then
    testRS = False
  Else
    testRS = True
  End If
End Function

minpic09.jpg

Sogar komplexe Serien-EMails lassen sich organisieren, wenn eine Datenbank im System angemeldet ist.


Zu diesem Artikel existieren Programmbeispiele
1099_096.zip

1099_096.txt