Lesen und Verstehen von SDKs

Von The Microsoft Scripting Guys

Sesame Script

Willkommen zu Sesame Script, der Kolumne für Anfänger in der Skriptprogrammierung. In dieser Reihe werden erste grundlegende Kenntnisse zur Skriptprogrammierung vermittelt, durch die Sie viele Aufgaben der Systemadministration unter Windows automatisieren können. Durch die vorgestellten Konzepte der Skriptprogrammierung werden Sie in der Lage sein, Skripts zu lesen und zu verstehen und Ihre ersten eigenen Änderungen oder Erweiterungen in Skripts vorzunehmen. Sollte Ihnen ein spezieller Aspekt der Skriptprogrammierung Schwierigkeiten bereiten, lassen Sie es uns wissen (in englischer Sprache). Sehr wahrscheinlich sind Sie nicht der Einzige, der vor einem bestimmten Problem steht. Dieser Artikel enthält Links zu englischsprachigen Seiten.

Lesen Sie auch die bisherigen Artikel im Sesame Script-Archiv.

Auf dieser Seite

Was bringt es mir?
Formatierung
Fett oder Kursiv
Platzhalter
Sprachreferenz: Ein weiteres Beispiel
Für Fortgeschrittene: WMI-SDK
Schlussbemerkung

In diesem Artikel erfahren Sie, wie sich der Code in Software Development Kits (SDKs) und Sprachreferenzen enträtseln lässt. Denjenigen, die sich noch nie mit diesem Thema befasst haben, möchten wir als Erstes erklären, warum sie sich überhaupt ein SDK oder eine Sprachreferenz ansehen sollen.

Was bringt es mir?

Ist das nicht immer die wichtigste Frage? Okay, wir befriedigen jetzt Ihre Neugier und beginnen mit unseren Ausführungen. Wir fangen mit einem Beispiel an, da dies oft die beste Erklärung ist. Angenommen, Sie suchen nach Informationen zu einem bestimmten Prozess. Sie haben im Script Center geblättert und einen "Hey, Scripting Guy"-Artikel zum Thema Wie ermittle ich das Datum und die Uhrzeit des Prozessstarts? gefunden. Im Folgenden sehen Sie das Skript, das diese Frage beantwortet:

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colProcessList = objWMIService.ExecQuery _
    ("Select * from Win32_Process Where Name = 'notepad.exe'")

For Each objProcess in colProcessList
    Wscript.Echo objProcess.CreationDate
Next

Hinweis: Wenn Sie den gesamten "Hey, Scripting Guy"-Artikel lesen (was Sie, nebenbei gesagt, immer tun sollten), werden Sie feststellen, dass das zurückgegebene Datum nur schwer lesbar ist. In einem weiteren Skript wird aber gezeigt, wie das Datum besser formatiert werden kann. Wir bleiben jedoch für unsere Zwecke bei der einfachen Version.

Sie werden jetzt denken "Prima, aber ich wollte eigentlich keine Informationen über das Datum und den Zeitpunkt, an dem der Prozess gestartet wurde. Ich möchte vielmehr den Pfad zu der ausführbaren Datei wissen, die den Prozess in Gang setzt." Wie können Sie nun herausfinden, ob ein Prozess Informationen über den Pfad zu seiner ausführbaren Datei bereitstellt? An der Select-Anweisung in diesem Code erkennen Sie, dass der Prozess über die Klasse Win32_Process gefunden werden kann. Wenn Sie sich nun die Klasse Win32_Process im WMI-SDK ansehen, wird Ihnen die lange Liste mit Eigenschaften auffallen:

Win32_Process-Klasse

Wenn Sie jetzt bereits wüssten, wie dieses SDK zu lesen ist, könnten Sie in der Liste die Eigenschaft ausfindig machen, die den Namen und den Pfad zur ausführbaren Datei enthält.

Okay, wir spannen Sie nicht länger auf die Folter. Die gesuchte Eigenschaft heißt ExecutablePath. Wenn Sie im obigen Skript CreationDate durch ExecutablePath ersetzen, haben Sie das gewünschte Skript erzeugt.

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colProcessList = objWMIService.ExecQuery _
    ("Select * from Win32_Process Where Name = 'notepad.exe'")

For Each objProcess in colProcessList
    Wscript.Echo objProcess.ExecutablePath
Next

Damit ist der Beweis erbracht, dass schon geringe Kenntnisse über SDKs das Leben wirklich erleichtern. Also sehen wir uns das Wenige, das Sie wissen müssen, näher an.

Formatierung

Bevor wir jedoch mit der Erläuterung von SDKs beginnen, müssen wir kurz vom eigentlichen Thema abweichen und ein paar Worte zum Webpublishing bei Microsoft verlieren.

Wie Sie sicher schon festgestellt haben, ist die Microsoft-Website relativ umfangreich. Sie ist sogar sehr umfangreich. Aufgrund ihrer Größe musste sie in viele Abschnitte unterteilt werden, die von verschiedenen Autoren betreut werden. So gibt es beispielsweise einen MSDN-Abschnitt (der aus vielen kleineren Abschnitten besteht) sowie einen TechNet-Abschnitt (der ebenfalls viele Unterabschnitte enthält). Die einzelnen Abschnitte werden auf unterschiedliche Weise verwaltet, und für das Erstellen und Veröffentlichen von Webinhalt werden verschiedene Tools und Vorlagen verwendet.

Sie fragen sich jetzt wahrscheinlich, warum wir Ihnen das alles erzählen. Dafür haben wir einen guten Grund: Wir möchten uns für das entschuldigen, was Sie zu sehen bekommen. Und die Scripting Guys sind gut, wenn es um Entschuldigungen geht. Wir betrachten es geradezu als Kunstform.

Wenn Sie nach SDKs für Microsoft-Produkte suchen, werden Sie oft auf den MSDN-Abschnitt stoßen. Im Folgenden sehen Sie ein Beispiel für eine Fundstelle:

SDK auf MSDN

Diese Seite enthält Informationen zur Methode Terminate der Klasse Win32_Process. Sehen Sie die Fett- und Kursivauszeichnungen im Codeabschnitt? Und genau hier kommt unsere Entschuldigung ins Spiel. MSDN wurde zur Unterstützung von Programmierern entwickelt. Deshalb befasst sich die Website in erster Linie mit Codesyntax und Ähnlichem. TechNet wendet sich dagegen nicht in erster Linie an Programmierer, sondern an IT-Profis wie Sie. Die TechNet-Artikel enthalten wichtige Informationen für Systemadministratoren und sind für diesen Zweck optimal aufbereitet. (Gelegentlich nutzen wir diese Artikel auch, da das Script Center ein Teil von TechNet ist.) Leider stehen aber bis heute keine Vorlagen zur Darstellung von Codesyntax zur Verfügung. Das bedeutet, dass wir die in MSDN gebräuchlichen Fett- und Kursivauszeichnungen nicht reproduzieren können. Also müssen wir uns hier und da mit Grafiken begnügen und versuchen, die Hintergründe so gut es geht zu erklären.

Hinweis: Wenn Sie nach dem Sinn des Lebens oder dem Grund dafür fragen, warum sich Hunde so gerne im Dreck wälzen, können wir Ihnen nicht helfen. Falls Sie aber wissen möchten, warum in den Skripts im Script Center weder Fett- noch Kursivauszeichnungen vorhanden sind, wissen wir die Antwort: Unsere Vorlagen unterstützen derartige Formatierungen nicht.

Damit haben wir diese Randerscheinung abgehandelt und wenden uns dem eigentlichen Thema dieses Artikels zu: dem Lesen und Verstehen von Referenzmaterial.

Fett oder Kursiv

Es gibt einige Grundregeln für die Syntax, an die sich allen Referenzen (mehr oder weniger) halten.

  1. Fett ausgezeichnete Elemente müssen genau so eingegeben werden, wie sie in der Syntaxanweisung stehen.

  2. Kursive Elemente sind – je nach Referenz – entweder Platzhalter, die durch Werte oder Variablen des Skripts ersetzt werden, oder optionale Elemente.

  3. Elemente in eckigen Klammern ([]) sind optional.

  4. Einfacher Text ist normalerweise ein Platzhalter.

Ist das alles etwas verwirrend? Okay, fangen wir mit etwas Lustigem an. Haben Sie jemals von Mad Libs® gehört? Mad Libs ist ein Spiel, bei dem in einer Geschichte Substantive, Verben, Adjektive usw. fehlen. Sie bitten jemanden, die fehlenden Wörter zu ergänzen, an der passenden Stelle einzufügen, und dann die Geschichte zu lesen. Ein Versuch:

  • Denken Sie sich ein Substantiv aus.

  • Denken Sie sich ein Verb (im Imperfekt) aus.

  • Denken Sie sich ein weiteres Substantiv aus.

Fügen Sie die Wörter jetzt in diese Satzstruktur ein:

Die SubstantivVerb überden Substantiv .

Hinweis: Verstehen Sie jetzt die Problematik mit Fett und Kursiv? Im Code sind diese Auszeichnungen gar nicht sichtbar, in normalem Text aber schon. Dafür können wir die Wörter nur unter Verlust der Leerzeichen zusammenführen. Dem Satz liegt folgende Struktur zugrunde:
Die Substantiv Verb über den Substantiv.

Lautet Ihr fertiger Satz "Die Kuh sprang über den Mond"? Wahrscheinlich nicht. Macht nichts. Mad Libs ist ja deshalb auch so unterhaltsam.

Das Einfügen von Variablen in eine VBScript-Anweisung ist möglicherweise nicht so lustig, funktioniert aber trotzdem genauso. Sehen wir uns die Syntax unseres alten Freunds Wscript.Echo an, wie sie in der Windows Script Host Reference dargestellt wird:

Wscript.Echo

Der erste Teil der Anweisung (object) ist nicht fett gedruckt. Es handelt sich hier also um einen Platzhalter, der durch ein tatsächliches Objekt ersetzt werden muss. Der nächste Teil der Anweisung enthält den Aufruf der Methode Echo. "Echo" ist fett gedruckt. Entsprechend der obigen Regel 1 müssen Sie dieses Wort genau so eingeben, wie es hier steht.

Dann folgt [Arg1]. Regel 3 besagt, dass Elemente in eckigen Klammern optional sind. Deshalb müssen auf das Wort "Echo" keine weiteren Angaben folgen. Wenn aber eine Ausgabe erfolgen soll, dann legen Sie diese mit Arg1 fest. Arg1 ist nicht fett gedruckt, also geben Sie nicht einfach Arg1 ein, sondern ersetzen Arg1 durch ein tatsächliches Argument. Die eckigen Klammern weisen lediglich darauf hin, dass Arg1 optional ist. Sie werden nicht in das Skript eingegeben.

Auf [Arg1] folgen [,Arg2], [,Arg3] und eine Ellipse (…). Wenn auf Arg1 ein weiteres Argument folgt (in unserem Fall Arg2), muss dieses durch ein Komma vom vorhergehenden getrennt werden. Noch einmal: Sie müssen Arg2 durch ein tatsächliches Argument ersetzen und bei der Eingabe die eckigen Klammern weglassen. Dasselbe gilt für Arg3. Die Ellipse besagt, dass Sie noch beliebig viele Argumente hinzufügen können. (Wenn keine Ellipse vorhanden wäre, dürften Sie nur die angegebene Anzahl von Argumenten verwenden. In diesem Fall wären es drei Argumente.)

So könnten Sie statt

object.Echo [Arg1] [,Arg2] [,Arg3] ...

zum Beispiel Folgendes eingeben:

Wscript.Echo "test" ,"script"

In diesem Fall ist Wscript das Objekt, Echo wird genauso wie in der Syntaxanweisung eingegeben, "test" ersetzt [Arg1] und "script" [,Arg2]. Und so sieht das Ergebnis aus:

Echo-Ausgabe

Hinweis: Leerzeichen zwischen den Argumenten und dem Komma haben keine Bedeutung. Die folgenden drei Anweisungen sind für VBScript identisch:

"test","script"
"test" ,"script"
"test"    ,    "script"

Vielleicht haben Sie gemerkt, dass die Syntaxanweisung keine Kursivauszeichnungen (erwähnt in Regel 2) enthält. Das liegt nur daran, dass in der Windows Script Host Reference keine derartigen Auszeichnungen in den Syntaxanweisungen verwendet werden. Alle Referenzen verwenden eigene Standards. Als Beleg hierfür sehen Sie im Folgenden ein Beispiel aus der ActiveX Data Objects Reference:

ADO-Syntaxbeispiel

Ärgern Sie sich nicht zu sehr über die Inkonsistenzen. Je länger Sie sich mit diesen Referenzen befassen, umso besser verstehen Sie sie. Die kleinen Ungereimtheiten wirken dann nicht mehr so verwirrend.

Platzhalter

Vielleicht fragen Sie sich, wie um alles in der Welt wir wissen konnten, dass das Objekt Wscript lauten soll und dass für Arg1 und Arg2 Zeichenfolgen eingefügt werden können? Ganz einfach: Diese Informationen haben wir aus der Referenz. Sehen wir uns den nächsten Abschnitt der WSH-Referenz für die Echo-Methode an:

Methodenplatzhalter

Wir sehen, dass das Objekt (object) als Wscript-Objekt definiert ist. So wissen wir, dass object.Echo immer Wscript.Echo ist. Bezüglich der Argumente teilt uns die Referenz mit, dass sie optional sind und die anzuzeigenden Zeichenfolgen enthalten müssen.

Sprachreferenz: Ein weiteres Beispiel

Werfen wir einen kurzen Blick auf ein weiteres, relativ einfaches Beispiel. Dieses Mal verwenden wir die Funktion DateAdd aus der VBScript Language Reference.

DateAdd-Funktion

Diese Funktion addiert ein Datum und einen Wert und gibt ein neues Datum zurück. Aber wie wird diese Funktion verwendet? Fangen wird mit dem Teil an, der fett ausgezeichnet ist:

DateAdd( )

Darauf folgt interval. Laut der Beschreibung von interval im Argumente-Abschnitt handelt es sich um eine Zeichenfolge. Beim Weiterlesen erfahren wir, dass diese Zeichenfolge aus einer speziellen Wertmenge bestehen muss, die weiter hinten in der Dokumentation aufgeführt ist. Wir kommen sofort darauf zurück.

Nun benötigen wir eine Zahl (number). Dem Argumente-Abschnitt entnehmen wir, dass es sich hierbei um die Zahl handelt, die zum Datum addiert werden soll. Angenommen, wird möchten das Datum und die Zahl 5 addieren. (Fünf was? Wir kommen auf diese Frage zurück, sobald wir uns wieder mit der interval-Einstellung befassen.) Bis jetzt sind wir so weit:

DateAdd( , 5, )

Das letzte Element ist das Datum. Die Beschreibung für dieses Element besagt, dass es sich um eine Variante oder ein Literal zur Darstellung des Datums handelt, zu dem interval addiert wird. Im vorherigen Artikel haben wir festgestellt, dass alle VBScript-Variablen vom Typ Variant sind. Deshalb hilft uns diese Beschreibung im Augenblick nicht viel weiter. Aber wir erfahren, dass es sich um ein Datum handelt. Also geben wir ein Datum ein:

DateAdd( , 5, "10/10/2006")

Warum haben wir das Datum in Anführungszeichen gesetzt? Wenn wir das nicht machen, spielt VBScript sein Datentyp-Ratespiel und stellt fest, dass dieser Wert nicht nur Zahlen enthält, sondern dass wir sogar eine Division damit ausführen. Schon allein deshalb muss es sich um eine Zahl handeln. Pflichtschuldig werden die Zahlen 10, 10 und 2006 dividiert, und das Ergebnis sieht etwas anders aus als erwartet.

Jetzt aber zurück zu interval, dem ersten Argument. Wenn wir weiter hinten in der Dokumentation nachsehen, finden wir einen Abschnitt mit dem Titel "Settings":

Funktionseinstellungen

In diesem Abschnitt sind die Zeichenfolgenwerte aufgeführt, die in die Funktion eingefügt werden können. Wenn wir beispielsweise zum Datum fünf Jahre addieren möchten, muss interval in Jahren bemessen werden. Entsprechend dem Abschnitt "Settings" lautet die interval-Zeichenfolge für Jahre "yyyy". Unser Funktionsaufruf sieht nun folgendermaßen aus:

DateAdd("yyyy", 5, "10/10/2006")

Fertig, oder? Nicht ganz. Wo ist unser neues Datum? Zur Beantwortung dieser Frage müssen wir an den Beginn der Dokumentation zurückkehren. Über der Syntaxanweisung wird erwähnt, dass diese Funktion ein Datum zurückgibt. Das bedeutet: Um das Datum zu erhalten, weisen wir die Ausgabe dieser Funktion einer Variablen zu:

newDate = DateAdd("yyyy", 5, "10/10/2006")

So, jetzt ist es passiert. Sie haben gerade mithilfe der VBScript Reference ein Intervall zu einem Datum addiert. Vergessen Sie nicht, dass Sie für alle diese Werte Variablen verwenden können. Im Folgenden sehen Sie ein vollständiges Skript, das diese Schritte ausführt und das neue Datum zurückgibt:

dtOldDate = "10/10/2006"
iTimeToAdd = 5
strInterval = "yyyy"

dtNewDate = DateAdd(strInterval, iTimeToAdd, dtOldDate)

Wscript.Echo dtNewDate

Für Fortgeschrittene: WMI-SDK

Jetzt wenden wir uns einem komplizierteren Beispiel aus dem Windows Management Instrumentation Software Development Kit zu. Wir gehen davon aus, dass Sie bereits mit WMI gearbeitet haben und mit der folgenden Anweisung etwas anfangen können. Sie stellt eine Verbindung zum WMI-Dienst auf dem lokalen Computer her:

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

In diesem Zusammenhang werden wir auch nicht erklären, wie die benötigten Klassen, Methoden oder Eigenschaften zu finden sind. Das ist ein umfassendes Thema, das nicht mit einigen Sätzen behandelt werden kann. Außerdem gibt es keine wirklich gute Antwort zu dieser Frage. Stattdessen nehmen wir einfach an, dass Sie die erforderlichen Elemente irgendwie gefunden haben, und nun im SDK nachsehen, wie diese verwendet werden. Fangen wir an.

In unseren bisherigen Beispielen haben wir immer mit den Methoden begonnen, die wir aufrufen wollten. In WMI beginnen wir mit der Klasse. Der Grund hierfür liegt darin, dass alle WMI-Eigenschaften und -Methoden zu einer Klasse gehören. Sobald wir wissen, um welche Klasse es sich handelt, können wird mithilfe des SDK herausfinden, welche Eigenschaften und Methoden die Klasse unterstützt und wie diese verwendet werden. (Eine Beschreibung von Klassen, Eigenschaften und Methoden und ihrer Beziehungen zueinander finden Sie im Artikel Eine Sitzung mit der Klasse.)

Die Klasse "Win32_Service"

In diesem Beispiel wollen wir herausfinden, wie sich der Status von Diensten, die auf einem Computer ausgeführt werden, ermitteln lässt. Dazu verwenden wir folgendes Skript:

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colRunningServices = objWMIService.ExecQuery("Select * from Win32_Service")

For Each objService in colRunningServices 
    Wscript.Echo objService.DisplayName  & VbTab & objService.State
Next

Beachten Sie, dass wir eine Abfrage für das Objekt Win32_Service ausführen. Unsere Abfrage gibt eine Auflistung aller Win32_Service-Objekte auf dem Computer zurück, die wir durchlaufen. Dann werden die Eigenschaften DisplayName und State dieser Dienste ausgegeben. (Ausführliche Informationen zum Durchlaufen von Sammlungen finden Sie im Artikel Schleifen.)

Eigenschaften von "Win32_Service"

Woher wissen wir, welche Eigenschaften benötigt werden? Wir sehen natürlich im WMI-SDK nach.

Eigenschaften von Win32_Service

Das SDK enthält die Definition der Klasse Win32_Service. Werfen wir einen Blick auf die erste Zeile:

class Win32_Service : Win32_BaseService

Anhand des ersten Elements (class) der Zeile erfahren wir, dass Win32_Service eine Klasse ist. (Wetten, dass Sie das auch selbst herausgefunden hätten.) Das zweite Element ist der Name der Klasse, also Win32_Service.

Danach folgen ein Doppelpunkt (:) und der Ausdruck Win32_BaseService. Was ist das? Diesen Teil der Anweisung können Sie getrost ignorieren. Wenn Sie möchten, können Sie sogar den Rest dieses Abschnitts überspringen. Sie sind noch da? Gut, dann erfahren Sie jetzt ein großes Geheimnis. Dieses Element ist die Klasse, von der Win32_Service abgeleitet ist. Weiter, noch nicht aufgeben, es kommt noch besser. In Programmiersprachen wie C und C++ können Sie Klassen erstellen, die Eigenschaften und Methoden definieren. Und Sie können Klassen erstellen, die auf diesen Klassen basieren (von ihnen abgeleitet sind). Die neue Klasse erbt alle Eigenschaften und Methoden der Ausgangsklasse und kann eigene Eigenschaften und Methoden hinzufügen. Sie kann sogar eine Eigenschaft oder Methode erstellen, mit der die gleichnamige Eigenschaft oder Methode der übergeordneten Klasse überschrieben wird. Langer Rede kurzer Sinn: Win32_Service ist eine Kopie von Win32_BaseService mit einigen kleinen Abweichungen (Änderungen oder Hinzufügungen) bezüglich der Eigenschaften und Methoden. Win32_BaseService ist die übergeordnete Klasse von Win32_Service. Programmiertechnisch korrekt ausgedrückt ist Win32_Service von Win32_BaseService abgeleitet.

Hinweis: Häufig kann aber in WMI eine im SDK enthaltene übergeordnete Klasse nicht für das Festlegen oder Abrufen von Daten verwendet werden. Der einzige Zweck einiger Klassen besteht darin, als Vorlage für andere Klassen zu dienen (andere Klassen können von ihnen abgeleitet werden). Zu dieser Kategorie gehört beispielsweise der größte Teil der Klassen, die mit CIM_ beginnen.

Diejenigen, die eine Kaffeepause eingelegt haben, sollten jetzt wieder zurückkommen.

Die nächste Zeile der Anweisung enthält eine öffnende geschweifte Klammer ({). Die schließende geschweifte Klammer (}) befindet sich am Ende der Anweisung (danach folgt ein Strichpunkt). So sieht die Standardsyntax für die Definition eines Codeblocks in Sprachen wie C und JScript aus. Alles, was sich innerhalb der geschweiften Klammern befindet, gehört zur Klasse Win32_Service. Ein Strichpunkt definiert das Ende einer Zeile. In VBScript stellen Sie an das Ende von Zeilen, die fortgesetzt werden sollen, einen Unterstrich. In JScript wird zeilenübergreifend gearbeitet. Das Ende einer Zeile wird dann mit einem Strichpunkt gekennzeichnet.

Innerhalb der geschweiften Klammern befindet sich eine Liste aller Eigenschaften, die zur Klasse Win32_Service gehören. Zu jeder Eigenschaft wird als erstes ihr Datentyp und danach ihr Name angezeigt. Werfen wir einen Blick auf die erste Eigenschaft:

boolean AcceptPause;

Hier erfahren wir, dass die Eigenschaft AcceptPause der Klasse Win32_Service einen booleschen Wert (True oder False) enthält. Wie Sie bereits wissen (zumindest, wenn Sie unseren vorherigen Sesame Script-Artikel gelesen haben), ist es für die Benutzer von VBScript wichtig, den Datentyp zu kennen. Dadurch wissen wir, welcher Typ von Daten zu erwarten ist, wenn ein Wert aus einer Eigenschaft gelesen wird, oder welcher Typ von Daten in eine Eigenschaft geschrieben werden muss. Außerdem lässt sich anhand des Datentyps erkennen, ob die Eigenschaft einen Einzelwert oder ein Array zurückgibt. Dies ist wichtig, da im Fall eines Arrays die Ausgabe des Rückgabewerts zu einem Fehler führt. Bei einem Array müssen Sie eine Schleife über das Array ausführen und jedes Element einzeln ausgeben. Eckige Klammern nach den Eigenschaftsnamen zeigen an, dass die Eigenschaft ein Array enthält. So gibt beispielsweise die Eigenschaft InsertionStrings der Klasse Win32_NTLogEvent ein Array zurück. Die Definition dieser Eigenschaft lautet:

string InsertionStrings[];

Da keiner der Eigenschaftsnamen in der Definition der Klasse Win32_Service eckige Klammern aufweist, wissen wir, dass diese Eigenschaften keine Arrays sind. Außerdem wissen wir, dass alle Eigenschaften der Klasse Win32_Service Nur-Lesen-Eigenschaften sind. Woher haben wir diese Information? Wieder aus dem SDK. Es gibt zwei Arten, um festzustellen, ob es sich um eine Nur-Lesen- oder eine Lesen-Schreiben-Eigenschaft handelt. Sie können einfach im SDK auf den Namen der Eigenschaft klicken. Daraufhin wird ein kleines Popup-Fenster mit einer Beschreibung der Eigenschaft geöffnet. Und Sie sehen, dass die Eigenschaft AcceptPause den Zugriffstyp Nur-Lesen hat:

Popup mit Eigenschaftsbeschreibung

Sie können auch nach unten zu den Eigenschaftsbeschreibungen blättern:

Eigenschaftsbeschreibungen

Die Eigenschaftsbeschreibungen sind das nützlichste Feature des SDK. Es ist zwar möglich, Eigenschaften aus anderen Quellen zu verwenden, z. B. aus Scriptomatic oder Wbemtest.exe. Anhand der Beschreibungen wissen Sie aber sofort, ob es sich um eine Lesen-Schreiben- oder eine Nur-Lesen-Eigenschaft handelt, und welches Verhalten bzw. welche Informationen von der Eigenschaft zu erwarten sind.

"Win32_Service"-Methoden

Angenommen, Sie möchten auf einem Computer einen Dienst starten. Mithilfe einer Eigenschaft können Sie überprüfen, ob der Dienst bereits läuft. Sie verwenden dazu natürlich die Eigenschaft Started. Die Aktion selbst, also das Starten des Dienstes, kann aber nicht mit einer Eigenschaft durchgeführt werden. Sie benötigen dazu eine Methode. Die Klasse Win32_Service verfügt über mehrere Methoden:

Win32_Service-Methoden

Es liegt auf der Hand, welche Methode Sie zum Starten eines Dienstes verwenden: StartService. Wenn wir im vorherigen Bildschirm auf die Methode StartService klicken, wird die vollständige Definition dieser Methode angezeigt:

StartService-Methode

Die Methode ist folgendermaßen definiert:

uint32 StartService()

Das erste Element in der Definition ist ein Datentyp: uint32. Der Datentyp bestimmt, welcher Typ von Wert beim Aufruf der Methode zurückgegeben wird. Mit anderen Worten: Wenn Sie StartService zum Starten eines Dienstes aufrufen und der Aufruf abgearbeitet ist, wird eine Zahl (in diesem Fall ein 32-Bit-Integer) zurückgegeben. Sie können dann im Abschnitt über Rückgabewerte (Return Values) der Dokumentation nachschlagen und feststellen, welche Bedeutung die zurückgegebenen Werte haben. Wenn Sie beim Aufruf von StartService den Rückgabewert 0 erhalten, wissen Sie, dass der Aufruf erfolgreich war. Die Rückgabe des Werts 10 weist darauf hin, dass der Dienst bereits ausgeführt wird. Das bedeutet, dass der Start des Dienstes fehlgeschlagen ist, weil er bereits läuft.

Wenn Sie sich die Methodendefinition (genauer gesagt, die Methodendeklaration) noch einmal ansehen, werden Sie feststellen, dass auf den Namen der Methode eine öffnende und eine schließende runde Klammer folgt. Sie müssen der Methode StartService also keine Informationen übergeben, damit sie ausgeführt werden kann. Das ist bei dieser Methode auch sinnvoll: Sie kennen ja den Dienst bereits, da Sie die Methode StartService für das gewünschte Dienstobjekt aufrufen. Deshalb sind keine weiteren Informationen erforderlich. Zur Demonstration sehen Sie im Folgenden ein Skript, das den Smart Card-Dienst startet und den Rückgabewert der Methode StartService ausgibt:

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colServiceList = objWMIService.ExecQuery _
    ("Select * from Win32_Service where Name='SCardSvr'")

For Each objService in colServiceList
    errReturn = objService.StartService()
    Wscript.Echo errReturn
Next

Weitere Methoden von "Win32_Service"

"Weitere Methoden" bedeutet im vorliegenden Fall "eine weitere Methode", da diese Kolumne ansonsten zu lang würde und außerdem gleich Essenszeit ist.

Die gerade vorgestellte Methode StartService besitzt keine Parameter. Wie bereits erwähnt, muss diese Methode nicht mit weiteren Informationen versorgt werden, damit sie ausgeführt werden kann. Für viele andere Methoden gilt dies aber nicht. Sehen wir uns beispielsweise die Methode ChangeStartMode der Klasse Win32_Service an.

ChangeStartMode-Methode

uint32 ChangeStartMode(
  string StartMode
);

ChangeStartMode gibt genauso wie StartService einen Wert des Typs uint32 (eine Zahl) zurück. Das SDK informiert Sie auch für diese Methode über die möglichen Rückgabewerte und deren Bedeutung.

Der Unterschied zwischen ChangeStartMode und StartService wird sofort deutlich, wenn Sie sich den Inhalt der Klammern ansehen. Nach StartService stehen leere Klammern, d. h., die Methode besitzt keine Parameter. Die Klammern nach ChangeStartMode enthalten aber einen Wert:

string StartMode

Kommt Ihnen dies bekannt vor? Erinnert Sie das nicht an die Eigenschaften, die wir uns früher angesehen haben? Die Deklaration ist identisch: ein Datentyp, auf den ein Name folgt. In diesem Fall handelt es sich um den Datentyp und den Namen des Parameters, der an die Methode übergeben wird.

Gehen wir noch einmal zurück, und untersuchen wir, warum ChangeStartMode einen Parameter hat. Wie Sie auf der Eigenschaftenseite des Smart Card-Dienstes sehen können, besitzen Dienste einen Starttyp:

Smart Card-Diensteigenschaften

In der grafischen Benutzeroberfläche (GUI) haben Sie die Wahl zwischen Automatic (Automatisch), Manuell (Manual) und Deaktiviert (Disabled). Wenn Sie den Starttyp (oder Startmodus) mit einem Skript ändern möchten, müssen Sie der Methode ChangeStartMode mitteilen, welcher Modus verwendet werden soll.

Und damit kommen wir zum Parameter StartMode zurück. Werfen wir im SDK einen Blick auf die Beschreibung dieses Parameters. Die erste Zeile der Beschreibung lautet:

[in] Start mode of the Windows base service.

Das erste Element ist [in]. Dies bedeutet, dass StartMode ein Eingabeparameter ist. (Im Fall eines Ausgabeparameters würde die Beschreibung mit [out] beginnen.) Ein Eingabeparameter ist ein Parameter, dem ein Wert zugewiesen werden muss. Im vorliegenden Fall weisen Sie diesem Parameter eine Zeichenfolge (String) zu, in der Sie den Startmodus angeben. Welche Art von Wert zugewiesen wird, wissen wir aufgrund des Datentyps des Parameters. Würde es sich hier um einen Ausgabeparameter handeln, müssten Sie in den Methodenaufruf eine leere Variable einfügen. Die Methode würde der Variable dann einen Wert zuordnen und diesen ausgeben.

Als Nächstes sehen Sie eine Tabelle:

Wert

Bedeutung

Boot

Gerätetreiber, der vom Betriebssystem-Lader gestartet wird. Dieser Wert gilt nur für Treiberdienste.

System

Gerätetreiber, der bei der Betriebssysteminitialisierung gestartet wird. Dieser Wert gilt nur für Treiberdienste.

Automatic

Dienst, der beim Systemstart vom Dienststeuerungs-Manager automatisch gestartet wird.

Manual

Dienst, der vom Dienststeuerungs-Manager gestartet wird, sobald ein Prozess die Methode StartService aufruft.

Disabled

Dienst, der nicht mehr gestartet werden kann.

In dieser Tabelle sind die Werte aufgeführt, die diesem Parameter zugewiesen werden können. Wenn Sie beispielsweise verhindern möchten, dass ein Dienst gestartet wird, weisen Sie der Methode ChangeStartMode die Zeichenfolge "Disabled" zu. Im folgenden Skript wird genau dies ausgeführt:

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colServiceList = objWMIService.ExecQuery _
    ("Select * from Win32_Service where Name='SCardSvr'")

For Each objService in colServiceList
    errReturn = objService.ChangeStartMode("Disabled")
    Wscript.Echo errReturn
Next

Das war nicht schwer, oder?

Schlussbemerkung

Das war alles für heute. Vielen Dank, dass Sie an unserem Seminar zu Sprachreferenzen und SDKs teilgenommen haben. Bitte werfen Sie beim Hinausgehen allen Bonbonpapierchen und Becher in den Abfalleimer. Und kommen Sie gut nach Hause.