Hey, Scripting Guy!Passen Sie auf, was Sie sagen!

Die Microsoft Scripting Guys

WÄHREND DES AMERIKANISCHEN Bürgerkriegs (in der Schlacht um Spotsylvania, um genau zu sein) war der General der Unionsarmee John Sedgwick entsetzt, als er sehen musste, wie sich seine Männer vor dem gelegentlichen Gewehrfeuer der Scharfschützen der Konföderierten, das zufällig in ihre Richtung zielte, verkrochen. Der Legende nach soll Sedgwick seinen Männern Folgendes gesagt haben: "Ich schäme mich für euch, dass ihr euch so feige versteckt. Auf die Entfernung können die nicht mal einen Elefanten treffen!" Nur wenige Augenblicke später wurde Sedgwick zum Offizier mit dem höchsten Rang, der in diesem Krieg getötet wurde. Vielleicht konnten die Scharfschützen der Konföderierten keinen Elefanten treffen, aber, sehr zum Pech für Sedgwick, einen General schon.

Natürlich braucht die Moral von der Geschichte nicht extra betont zu werden - nun, da Sie es sagen:"Halt Deinen Kopf unten, wenn jemand auf dich schießt!", wäre doch wohl die richtige Lehre aus dieser Geschichte, oder? Hmm - schlecht, dass wir daran nicht gedacht haben! Stattdessen haben wir die folgende Lehre gezogen: "Pass auf, was Du sagst, es könnte eines Tages auf Dich zurückfallen!" Das galt für General John Sedgwick, und das gilt wohl für die meisten Menschen. So erinnert sich z. B. kein Mensch mehr an Thomas Watson, langjähriger Chef von IBM, als einen der größten Arbeitgeber in der Geschichte der USA. Stattdessen wurde Watson unsterblich als der Mann, der sagte: "Ich glaube, es gibt da einen Markt für, sagen wir mal, fünf Computer!".

Interessanterweise gibt es keinerlei Belege dafür, dass Watson dies wirklich gesagt hat. Bestenfalls hat er einfach nur die Gedanken eines Anderen zu diesem Thema wiedergegeben. Aber wen kümmert das schon? Letzten Endes liefert uns der Gedanke, dass der Chef von IBM gesagt haben soll, dass es keinen Markt für Computer gäbe, eine so tolle Geschichte, dass wir uns das nicht durch so einen Quatsch wie Tatsachen kaputt machen lassen, oder?

Übrigens hat Watson tatsächlich gesagt: "Wenn Du Erfolg haben willst, verdoppele Deine Fehlerrate!". Diesen Rat haben sich die Scripting Guys sehr zu Herzen genommen.

Nun, jedenfalls den Teil mit der Verdopplung der Fehlerrate.

Und dann gibt es noch dieses Zitat: "Wenn Du Skripts in VBScript schreibst, hast Du keinen Zugriff auf .NET Framework." Zugegebenermaßen ist die Aussage, dass Microsoft® .NET Framework für Skriptschreiber nicht zugänglich ist, nicht ganz so geschichtsträchtig wie "Auf die Entfernung können die nicht mal einen Elefanten treffen!" oder "Ich glaube, es gibt da einen Markt für, sagen wir mal, fünf Computer!". Eine solche Aussage liegt jedoch mindestens genauso daneben. Es stimmt, dass .NET Framework für Entwickler in C# und Visual Basic® geschrieben wurde, und es stimmt, dass VBScript native Klassen in .NET Framework nicht instanzieren kann. Aber das bedeutet nicht, dass .NET Framework für Skriptschreiber unzugänglich wäre, jedenfalls vollständig.

Ja, Sie haben Recht: wir können nicht leugnen, dass die Mehrheit der Klassen von .NET Framework außerhalb der Reichweite von VBScript liegt. Es gibt jedoch eine beträchtliche Anzahl von Klassen in .NET, die über eine COM-aufrufbare Kapsel verfügen. Das heißt, dass diese Klassen über eine COM-Schnittstelle verfügen, was einfach nur bedeutet, dass durch eine Skriptsprache wie VBScript auf diese Klassen zugegriffen werden kann. Sie sagen, dass das kaum zu glauben ist? Dann werfen Sie einen Blick auf den Abschnitt HKEY_CLASSES_ROOT in Ihrer Registrierung, wie in Abbildung 1 dargestellt. Dort finden Sie alle möglichen Arten von Klassen, die mit "System" beginnen.

Abbildung 1 'System'-Klassen in der Registrierung

Abbildung 1** 'System'-Klassen in der Registrierung **(Klicken Sie zum Vergrößern auf das Bild)

Die meisten dieser Objekte sind Klassen aus .NET Framework und für die meisten dieser Klassen können mittels VBScript Instanzen erzeugt werden.

Na bitte!

Natürlich bedeutet das nicht, wie jeder bestätigen kann, der schon einmal ein Produkt spät in der Nacht bei einem Shoppingsender bestellt hat, dass man etwas unbedingt tun sollte, nur weil man es kann (das ist häufig der Grund, warum derartige Produkte nicht in Läden angeboten werden). Natürlich können Sie in einem Skript eine Instanz der Klasse "System.ContextMarshalException" erzeugen. Wir haben aber keine Ahnung, warum Sie das tun sollten oder was Sie mit einer solchen Instanz anfangen könnten.

Aber das trifft nicht auf alle Klassen in .NET Framework zu. So bezieht sich z. B. einer der gefürchtetsten Schrecken in der Welt der Skripte auf die Tatsache, dass es keine simple Möglichkeit zum Sortieren von Listeneinträgen gibt. Wenn Sie eine Liste in alphabetischer Reihenfolge sortieren möchten, müssen Sie entweder eine unverknüpfte Menge an Datensätzen bemühen oder auf eigene Faust eine komplizierte Sortierfunktion schreiben, wie z. B. die folgende Funktion zum Sortieren von Blasen (Leser mit empfindlichem Magen fahren am besten mit dem nächsten Abschnitt fort):

For i = (UBound(arrNames) - 1) to 0 Step -1
    For j= 0 to i
        If UCase(arrNames(j)) > 
          UCase(arrNames(j+1)) Then
            strHolder = arrNames(j+1)
            arrNames(j+1) = arrNames(j)
            arrNames(j) = strHolder
        End If
    Next
Next

Machen Sie sich nichts daraus: wir haben den Code geschrieben, aber wir wissen auch nicht ganz genau, was das alles bedeutet!

Nun, wie kann uns .NET Framework in einer solchen Situation helfen? Um diese Frage zu beantworten, schauen wir uns ein sehr einfach gehaltenes und geradliniges Skript an:

Set DataList = CreateObject _
      ("System.Collections.ArrayList")

DataList.Add "B"
DataList.Add "C"
DataList.Add "E"
DataList.Add "D"
DataList.Add "A"

DataList.Sort()

For Each strItem in DataList
    Wscript.Echo strItem
Next

Wie Sie sehen können, erzeugen wir hier eine Instanz der .NET Framework-Klasse "System.Collections.ArrayList". Anschließend fügen wir mit Hilfe der Methode "Add" fünf Elemente in die Liste ein. Das ist alles schön und gut, mit einer Ausnahme: wir haben diese Einträge irgendwie planlos eingefügt (B, C, E, D, A), aber wir müssen die Einträge in der Reihenfolge (A, B, C, D, E) anzeigen. Es wird Zeit, dass wir den Code zum Sortieren von Blasen hervorkramen, stimmt's?

Falsch! (Entschuldigen Sie, dass wir so direkt sind, aber falsch ist nun einmal falsch.) Wie sich herausstellen wird, brauchen wir den Code für die Blasensortierung nicht. Alles was wir tun müssen, ist die Methode "Sort" für Array-Listen aufzurufen.

DataList.Sort()

Und das war's schon! Mit dieser einzigen Zeile an Code können wir alle Elemente in unserer Array-Liste sortieren.

Wollen Sie Beweise? Toll, cleveres Publikum! Das geht schon in Ordnung. Wir haben damit gerechnet, dass es diesen oder jenen ungläubigen Thomas in unserer Leserschaft gibt. Aus diesem Grund enthält das Skript eine "For Each"-Schleife, die alle Elemente in der Liste abarbeitet und den Wert der einzelnen Elemente auf dem Bildschirm ausgibt.

For Each strItem in DataList
    Wscript.Echo strItem
Next

Nun, hier ist eine Frage, mit der Sie sich beschäftigen können: Was bekommen wir zurück, wenn wir dieses Skript ausführen?

Gut getippt:

A
B
C
D
E

Hübsch, nicht wahr?

Hmm, wir merken, dass einige von Ihnen noch nicht ganz glücklich sind. Sie sagen, dass das zwar alles gut und schön ist, aber was Sie eigentlich wollten, war die Ausgabe dieser Werte in absteigender Reihenfolge, also eine Liste von Z bis A anstatt einer Liste von A bis Z. Nun, wenn uns nicht mal das gelingt. . .

Hey, kein Problem! Sie brauchen doch bloß zu fragen:

Set DataList = CreateObject _
      ("System.Collections.ArrayList")

DataList.Add "B"
DataList.Add "C"
DataList.Add "E"
DataList.Add "D"
DataList.Add "A"

DataList.Sort()
DataList.Reverse()

For Each strItem in DataList
    Wscript.Echo strItem
Next

Sie haben Recht: das sieht doch verdammt ähnlich aus wie das weiter oben dargestellte Skript, oder? Nun, es gibt da jedoch eine wichtige Ergänzung! Betrachten Sie sich diese einzelne Codezeile, die wir eingefügt haben, die Zeile gleich nach der Methode "Sort":

DataList.Reverse()

Sehen Sie das? Nach dem Sortieren der Liste in aufsteigender Reihenfolge haben wir die Methode "Reverse" aufgerufen, die, welch Überraschung, die Reihenfolge aller Elemente im Array umkehrt. Was bringt uns das? Eine Ausgabe, die so aussieht:

E
D
C
B
A

Schwer beeindruckend, nicht wahr?

Aber warten Sie! Es kommt noch besser. Haben Sie jemals versucht, ein Element aus einem Array in VBScript zu löschen? Nein, nicht weinen! Wir haben nicht vor, das von Ihnen zu verlangen. Stattdessen zeigen wir Ihnen, wie einfach ein Element aus unserer Array-Liste in .NET Framework gelöscht werden kann. Mögen Sie den Buchstaben D nicht? Dann werden Sie ihn eben los! Hier sehen Sie ein Skript, das eine Array-Liste erzeugt, die Liste sortiert und anschließend den Eintrag für D löscht:

Set DataList = CreateObject _
  ("System.Collections.ArrayList")

DataList.Add "B"
DataList.Add "C"
DataList.Add "E"
DataList.Add "D"
DataList.Add "A"

DataList.Sort()
DataList.Remove("D")

For Each strItem in DataList
    Wscript.Echo strItem
Next

Auch hier sollten Sie sich die unscheinbare Codezeile direkt nach der Methode "Sort" ansehen:

DataList.Remove("D")

Hier haben wir mit Hilfe der Methode "Remove" das Element gleich D gelöscht. Und hier sehen Sie das Resultat der Ausführung des Skipts:

A
B
C
E

Hasta la vista, D!

Und versäumen Sie nicht den besten Teil: Wir können ein Element löschen, ohne Größe und Dimension des Arrays ändern zu müssen. Das ist doch echt clever. Natürlich können wir auch Elemente in das Array einfügen, ohne Größe und Dimension des Arrays ändern zu müssen. Sagen Sie uns nicht, dass dadurch Ihr Skriptschreiberleben nicht einfacher würde!

Ob Sie es glauben oder nicht, wir haben bisher nicht einmal die Schale von dem angekratzt, was Sie mit Array-Listen in .NET Framework anstellen können. (Weitere Informationen finden Sie unter arraylist entry in the .NET Framework SDK (in Englisch)).

Ist die Arrayliste hilfreich für Skriptschreiber? Lassen Sie es uns so sagen: Seit wir die Array-Liste aus .NET Framework kennen, wissen wir nicht so recht, warum Sie jemals das in VBScript integrierte Array verwenden sollten, jedenfalls nicht für so einfache Listen, wie wir sie hier verwendet haben.

Zugegeben, wir Scripting Guys haben nicht einmal eine ermüdende Übersicht über .NET Framework erstellt, nur um herauszufinden, welche Klassen hilfreich für Skriptschreiber wären (und welche Klassen möglicherweise nicht). Daran arbeiten wir noch. In der Zwischenzeit können Sie ja im gesamten .NET Framework SDK herumstöbern. Es hat den Anschein, dass wir bei jedem Herumkramen im SDK etwas Neues und Interessantes finden, dass für Skriptschreiber nützlich sein könnte.

So, zum Beispiel? Nun, wie wär's mit dem Erzeugen von Zufallszahlen? Möchten Sie mit Hilfe des Zufallszahlengenerators in VBScript eine Zufallszahl zwischen 1 und 100 erzeugen? Kein Problem! Schreiben Sie einfach einen solchen Code auf:

Randomize
Wscript.Echo Int((100 - 1 + 1) * Rnd + 1)

Haben Sie sich diese Formel merken können? Falls nicht, keine Panik! Es zeigt sich, dass die Verwendung der Klasse "System.Random" aus .NET Framework wesentlich einfacher und intuitiver ist:

Set objRandom = CreateObject("System.Random")
Wscript.Echo objRandom.Next_2(1,100)

Sehr wahrscheinlich werden Sie das ohne große Erläuterung einsehen. Wir geben Ihnen trotzdem eine kurze Erläuterung, und wenn es nur deshalb ist, weil TechNet Magazin diese Vorstellung hat, dass Kolumnisten jeden Monat wirklich etwas schreiben sollten. (Fragen Sie uns nicht, warum - das ist deren Ansicht, nicht unsere.)

Wie Sie sehen können, haben wir eine Instanz der Klasse "System.Random" angelegt und anschließend die Methode "Next_2" aufgerufen und dabei zwei Parameter übergeben:

  • 1, die Anfangszahl in unserem Intervall (denken Sie daran, dass wir hoffentlich eine Zufallszahl zwischen 1 und 100 erzeugen werden).
  • 100, die Obergrenze unseres Intervalls.

Mehr gibt es nicht zu tun.

Sieht so aus, als hätten wir noch Zeit für eine abschließende Frage. Ja bitte, Sie im grünen Hemd! Wer genau von Ihnen hat eigentlich behauptet, dass Skriptschreiber keinen Zugriff auf .NET Framework haben? Nun, um ganz ehrlich zu sein, als wir anfingen zu - oh, ich glaube, die Zeit ist um. Bis zum nächsten Monat!

Tolle Zeiten, tolle Zeiten

Es ist ja fast Februar, und das kann nur eines bedeuten. Nein, nicht Valentinstag. Nein, auch nicht der Tag des Präsidenten. Oh, um Himmels Willen, Murmeltiertag? Nein, je näher der Februar kommt, desto näher kommen die 2007 Winter Scripting Games, der weltweit wichtigste (wahrscheinlich der weltweit einzige) internationale Wettkampf im Skriptschreiben. Die Games in diesem Jahr werden wohl größer und besser als je zuvor. In diesem Jahr spielen wir in vier Ligen:

  • Beginners VBScript
  • Advanced VBScript
  • Beginners Windows PowerShell™
  • Advanced Windows PowerShell

Weitere Informationen finden Sie unter 2007 Winter Scripting Games Homepage (in Englisch).

Was ist das? Oh, danke! Und, nun ja, auch noch einen glücklichen Murmeltiertag für Sie alle!

Laden Sie heute noch Windows PowerShell herunter

Windows PowerShell 1.0 kann nun heruntergeladen werden. Und es kostet nichts! Wie können Sie sich das entgehen lassen? Laden Sie die Software herunter und arbeiten Sie noch heute mit PowerShell!

Die Microsoft Scripting Guys arbeiten für- nun gut, sind angestellt bei - Microsoft. Wenn Sie nicht gerade Baseball (oder verschiedenste andere Aktivitäten spielen/trainieren/anschauen, kümmern sie sich um das TechNet Script Center. Schauen Sie mal rein unter www.scriptingguys.com.

© 2008 Microsoft Corporation und CMP Media, LLC. Alle Rechte vorbehalten. Die nicht genehmigte teilweise oder vollständige Vervielfältigung ist nicht zulässig.