![]() |
![]() |
Mittlerweile sind wir in der Lage, mittels Zusammenfügen einiger Bausteine, die wir gelernt haben, doch einiges zu bewerkstelligen. In diesem Kapitel wollen wir das anhand ein paar Systemsteuerungsaufgaben für Windows XP (!) mal ankosten. Die Bausteine, die wir benutzen werden, sind:
Von diesen vier Bausteinen fehlt uns nur noch der letzte:
Dieser ist ganz einfach. Mittels SHELL "Befehl" können Sie ein beliebiges DOS-Kommando abschicken. Also z.B. SHELL "copy A:\*.* C:\temp" würde aus QBASIC heraus alle Dateien des Diskettenlaufwerks nach C:\temp kopieren. Sogar das Ausführen von Batch-Dateien klappt so: QBASIC "back.bat" führt das Batchskript back.bat aus. Und jetzt machen Sie mal was ganz Lustiges: Starten Sie mal folgendes Programm:
SHELL "qbasic"
Was passiert? Scheinbar nichts. Ausser, dass der Eingangsbildschirm, bei dem man die ESC-Taste drücken muss, wieder erscheint. Und dann das Programm verschwunden ist. Das ist auch kein Wunder - wir haben aus dem alten QBASIC heraus ein neues QBASIC gestartet! Beenden wir es über Datei->Beenden, dann kommt zuerst der DOS- Bildschirm wieder mit der Aufforderung, eine Taste zu drücken. Und dann kommt wieder unser alter QBASIC-Schirm mit Programm.
Nehmen wir an, wir wollen ein Programm schreiben, das ein anderes Programm so installiert, dass es als DOS-Befehl aus jedem Verzeichnis aufgerufen werden kann. Das zu installierende Programm liege als Binary vor, also als Befehl der Form "myprog.exe".
In jedem Windowssystem gibt es ein Verzeichnis, das von vornherein im Pfad der Kommandozeile steht und somit nach Befehlen durchsucht wird, wenn man auf der Kommandozeile einen Namen eingibt: Das Windowsverzeichnis selbst. Nichts einfacher also, als unser myprog.exe ins Windowsverzeichnis zu kopieren (wenn das auch nicht feine englische Art eines Installationsprogramms ist - aber es funktioniert.)
Unser Installationsprogramm soll auf jeder Windowsversion bis zur neuesten laufen. Nun sind die Windowsverzeichnisse aber alles andere als einheitlich. Schon deshalb, weil das Systemlaufwerk nicht immer C: sein muss. Was tun? Wie finden wir heraus, wo das Windows-Verzeichnis ist? Das klingt jetzt schon ganz schön kompliziert.
Ist aber nicht so schwer. Als erstes müssen wir wissen, dass es ein Windows/DOS-Kommando namens SET gibt. Öffnen Sie mal eine Konsole und geben Sie SET+enter ein. Wenn ich das hier auf meiner Maschine eingebe, dann kommt folgendes:
COMSPEC=C:\WINNT\SYSTEM32\COMMAND.COM COMPUTERNAME=SCHATZ EDPATH=C:\progra~1\WATCOM\EDDAT HOMEDRIVE=C: HOMEPATH=\ INCLUDE=C:\progra~1\WATCOM\H;C:\progra~1\WATCOM\H\NT LOGONSERVER=\\SCHATZ MXBIN=D:\Programme\FireDaemon MXHOME=D:\Programme\FireDaemon NTRESKIT=D:\Programme\reskit1 NUMBER_OF_PROCESSORS=1 OS=Windows_NT OS2LIBPATH=C:\WINNT\system32\os2\dll; PATH=C:\winnt;C:\winnt\system32;C:\PROGRA~1\dosprog\tc\bin;C:\progra~1\dosprog\d os6 PATHEXT=.COM;.EXE;.BAT;.CMD PROCESSOR_ARCHITECTURE=x86 PROCESSOR_IDENTIFIER=x86 Family 6 Model 7 Stepping 3, GenuineIntel PROCESSOR_LEVEL=6 PROCESSOR_REVISION=0703 PROMPT=$P$G SYSTEMDRIVE=C: SYSTEMROOT=C:\WINNT TEMP=C:\TEMP TMP=C:\TEMP USERDOMAIN=SCHATZ USERNAME=schatz USERPROFILE=C:\WINNT\Profiles\schatz WATCOM=C:\progra~1\WATCOM WWINHELP=F:\BINW
Damit wissen Sie schon ziemlich viel über mich und meinen PC - sogar meinen Nachnamen. Sie wissen zumindest, dass ich auf einer ollen NT-Maschine mit einer ziemlich schlaffen CPU arbeite (PROCESSOR_IDENTIFIER). Was sehen wir hier? Wir sehen die voreingestellten Systemvariablen. Genau. Das sind Betriebssystem- variablen, die man abfragen und auch neu setzen kann. Die meisten davon sind Strings. Und eine davon enthält das Windows-Verzeichnis: SYSTEMROOT. Bingo.
Die nächste Aufgabe ist es, den Wert für SYSTEMROOT in unser Programm zu bekommen. Nun, wir haben im Kapitel Feine DOS-Fähigkeiten im Abschnitt "Umleitungen und Pipes" gelernt, dass man die Ausgabe eines DOS-Befehls in eine Datei umleiten kann. Geben wir also in unserem QBASIC-Verzeichnis "SET > set.txt" an, so leiten wir die Liste, was wir gerade noch auf dem Bildschirm gesehen haben, in die Datei set.txt um.
So, die nächste Aufgabe besteht nun darin, den Wert einer bestimmten Systemvariablen aus set.txt auszulesen. Das ist die Sache mit dem Dateien lesen. Hier muss man ein bisschen clever vorgehen, nämlich das Übungsergebnis aus dem vorigen Kapitel benutzen, bei dem es darum ging, eine search-Routine für Textdateien zu schreiben. Die die Textdatei nach einem bestimmten Schlüsselwort durchkämmt. Genau so etwas brauchen wir jetzt. Wenn Sie also die Übung noch nicht gemacht haben, dann schreiben Sie jetzt Ihre Routine "searchtextfile"! Ergebnis der Routine soll ein String mit der Zeile sein, in der das Schlüsselwort zum ersten Mal vorkommt. Kommt es in der Datei nicht vor, soll der String leer sein. Die Suche soll Gross- und Kleinschreibung nicht beachten.
Meine Lösung dafür sieht so aus:
'--------------------------------------------------------- 'Lookstring: 'Routine fuer das Suchen eines Strings in einer Textdatei '--------------------------------------------------------- 'Sucht in #1 '#1 muss geoeffnet sein 'Suchstring: such$ 'Rueckgabewert 1: rueck$ 'Rueckgabewert 2: suchpos 'Enthaelt die Zeile mit dem Suchstring 'by C. Schatz 2003, Programmiertutorial GOTO main lookstring: found = 0 WHILE (NOT EOF(1) AND found = 0) LINE INPUT #1, a$ suchpos = INSTR(LCASE$(a$), LCASE$(such$)) IF (suchpos > 0) THEN found = 1 WEND IF (found = 0) THEN rueck$ = "": suchpos = 0 ELSE rueck$ = a$ RETURN 'Test '--------- main: SHELL "set > set.txt" OPEN "set.txt" FOR INPUT AS #1 such$ = "systemroot" GOSUB lookstring CLOSE #1 PRINT rueck$ PRINT suchpos
Schauen wir uns diese Lösung einmal an. Was fällt Ihnen auf?
So. Das Hauptprogramm zeigt schon, wie wir nun ganz elegant an die Systemvariablen rankommt, auch z.B. an das temporäre Verzeichnis des Rechners. Wir müssen nun nur noch aus der richtigen Zeile des Variablenwert extrahieren. Das ist ziemlich einfach. Wir ermitteln mit INSTR() die Position des Gleichheitszeichens und nehmen dann den String ab einem Zeichen hinter dieser Position:
winpath$=MID$(rueck$,INSTR(rueck$,"=")+1,len(rueck$))
Die Zeile ist allerdings ein bisschen unübersichtlich. "Sprechender" wäre es, sie in mehrere Zeilen aufzuteilen:
posstart=INSTR(rueck$,"=")+1 IF (posstart=1) THEN STOP 'Hups! Kein Gleichheitszeichen! posend=LEN(rueck$) winpath$=MID$(rueck$,posstart,posend)
Der Rest ist nun einfach. Nehmen wir an, wir wollen das File von Diskette ins Windowsverzeichnis kopieren. Dann bilden wir den ganzen DOS-Befehl als String: cmd$="copy A:\"+fname$+" "+winpath$ und übergeben ihn der SHELL: SHELL(cmd$). fname$ enthält den Filenamen, z.B. "myprog.exe". Und das war's dann.