Einbettung von BASIC ins Betriebssystem

Programme aus BASIC heraus starten

GWBASIC.EXE als auch QuickBASIC bieten mit dem SHELL-Kommando die Möglichkeit an, Programme ausserhalb von BASIC direkt auf DOS/Windowsebene laufen zu lassen. Dabei funktioniert dies auch mit 32-Bit-Applikationen sogar bestens, also beispielsweise mit

10 ' Internet Explorer 5.01 aus GWBASIC.EXE heraus!
20 SHELL "C:\PROGRA~1\INTERN~1\IEXPLORE http://www.hofen.ch/~andreas/"

einen Webbrowser zu starten. Siehe auch BASIC in modernen Betriebssystemumgebungen.

Anmerkung für Amiga-Benutzer: Dort gibt es leider :-( keinen SHELL-Befehl, so dass Sie auf CALL Exec&() der dos.library ausweichen müssen.

Achtung konventioneller Speicher!

Achtung: Denken Sie immer daran, dass GWBASIC.EXE und QuickBASIC für DOS reine Real Mode-Programme sind, welche also im Intel 8088/8086-Modus wie bei einem uralten IBM PC/XT laufen! Aus diesem Grund unterliegt die Speicherverwaltung voll der bekannten 640 KB-Limite, selbst wenn Ihr PC mit 256 MB Arbeitsspeicher bestückt ist.

Mit folgenden Schritten können Sie den Verbrauch recht eindrücklich messen:

C:\BASICPRG>mem

Speichertyp               Insgesamt  =   Verwendet  +     Frei
-----------------         ----------     ---------      ---------
Konventioneller                 640K           27K           613K
Hoher                           123K           72K            51K
Reserviert                      128K          128K             0K
Erweiterung (XMS)             9'349K        2'407K         6'942K
-----------------         ----------     ---------      ---------
Insg. Speicher               10'240K        2'634K         7'606K

Insg. unter 1 MB                763K           98K           664K

Maximale Größe für ausführbares Programm           613K  (628'000 Byte)
Größter freier Block im hohen Speicherblock         51K   (51'952 Byte)
MS-DOS ist resident im oberen Speicherbereich (High Memory Area).

C:\BASICPRG>gwbasic

GW-BASIC 3.23
(C) Copyright Microsoft 1983,1984,1985,1986,1987,1988
60300 Byte frei
Ok
shell

Microsoft(R) Windows 98
   (C)Copyright Microsoft Corp 1981-1998.

C:\BASICPRG>mem

Speichertyp               Insgesamt  =   Verwendet  +     Frei
-----------------         ----------     ---------      ---------
Konventioneller                 640K          108K           532K
Hoher                           123K           72K            51K
Reserviert                      128K          128K             0K
Erweiterung (XMS)             9'349K        2'407K         6'942K
-----------------         ----------     ---------      ---------
Insg. Speicher               10'240K        2'715K         7'525K

Insg. unter 1 MB                763K          180K           583K

Maximale Größe für ausführbares Programm           532K  (544'560 Byte)
Größter freier Block im hohen Speicherblock         51K   (51'952 Byte)
MS-DOS ist resident im oberen Speicherbereich (High Memory Area).

C:\BASICPRG>exit
Ok
print 628000 - 544560
 83440 <= Rund 81½ KB werden von GWBASIC.EXE belegt!
Ok
system

C:\BASICPRG>_

Bei QBASIC.EXE ist es erheblich mehr: Rund 367¼ KB dieser wertvollen 640 KB konventionellen Speicher gehen weg! Aus diesem Grund macht es in einem solchen Fall Sinn, auch unter Windows 95 und 98 die beiden Dateien CONFIG.SYS und AUTOEXEC.BAT wie in den guten, alten MS-DOS 6.22/Windows 3.1x-Zeiten zu optimieren. Ob das gute, alte MEMMAKER.EXE unter Windows 95 und 98 auch noch eingesetzt werden kann, ist mir unbekannt, manuelle Änderungen wie beispielsweise

DEVICE=C:\WINDOWS\HIMEM.SYS /VERBOSE
DEVICE=C:\WINDOWS\EMM386.EXE NOEMS HIGHSCAN VERBOSE

am Anfang der Datei C:\CONFIG.SYS einfügen sowie alle Gerätetreiber mit LH laden und innerhalb der AUTOEXEC.BAT vor jedem TSR ein LOADHIGH oder LH voranstellen sollten Sie in jedem Fall versuchen.

Unterschied zwischen END und SYSTEM

Diese Frage erhielt ich schon einige Male per e-Mail zugestellt. Daher ganz kurz und bündig:

In beiden Fällen wird Ihr Programm beendet. Während Sie bei END noch in der BASIC-Entwicklungsumgebung bleiben, wird mit SYSTEM BASIC vollständig verlassen.

GWBASIC.EXE-Programmierer sollten dabei beachten, ihr Programm vorher mit save gespeichert zu haben, da keine Sicherheitsabfrage stattfindet!

Hinweis: Bei als .EXE-Datei übersetzten Programmen entfällt dieser Unterschied, da Sie nach Programmende sowieso wieder ins DOS zurückkommen.

Das Gegenstück dazu: BASIC-Programme in Gesamtsysteme integrieren

Im folgenden zeige ich Ihnen, wie Sie ein BASIC-Programm in eine .BAT-Datei integrieren können. Eine nützliche Anwendung davon ist das Aufrufen eines BASIC-Programms innerhalb der AUTOEXEC.BAT beim Systemstart, beispielsweise ein Startmenü.

Variante für GW-BASIC

Erstellen Sie mit EDIT.COM eine Datei MEINBAT.BAT mit folgendem Inhalt:

@ECHO OFF
REM Dies ist eine COMMAND.COM-Stapelverarbeitungsdatei für MS-DOS
ECHO Jetzt geht's dann gleich ins BASIC hinein
GWBASIC MEINPROG
ECHO BASIC-Programm fertig, wieder MS-DOS

Erstellen Sie noch in GWBASIC.EXE folgende kleine Programm MEINPROG.BAS

10 ' Wir sind in BASIC
20 PRINT "Jetzt läuft gerade mein BASIC-Programm"
30 SYSTEM

So, und nun können Sie das Ganze mit

C:\BASICPRG>meinbat

einmal laufen lassen.

Variante für QuickBASIC

Diese Variante betrifft nur die Interpreter-Version QBASIC.EXE.

Datei MEINBAT.BAT

@ECHO OFF
REM Dies ist eine COMMAND.COM-Stapelverarbeitungsdatei für MS-DOS
ECHO Jetzt geht's dann gleich ins BASIC hinein
QBASIC /RUN MEINPROG
ECHO BASIC-Programm fertig, wieder MS-DOS

Datei MEINPROG.BAS

' Wir sind in BASIC
PRINT "Jetzt läuft gerade mein BASIC-Programm"
SYSTEM

Beim BASIC-Compiler entfallen bekanntlich all diese Umwege.

Zugriff auf Umgebungsvariablen

Sowohl MS-DOS als auch Windows verwenden zahlreiche Umgebungsvariablen:

C:\WINDOWS>set
TMP=C:\WINDOWS\TEMP
TEMP=C:\WINDOWS\TEMP
winbootdir=C:\WINDOWS
COMSPEC=C:\WINDOWS\COMMAND.COM
PATH=C:\WINDOWS;C:\WINDOWS\COMMAND;E:\DOS\EXTRAS;E:\DOS
PROMPT=$p$g
windir=C:\WINDOWS
BLASTER=A220 I5 D1 H5 P330 T6 E620
CMDLINE=gwbasic

C:\WINDOWS>_

Sowohl GWBASIC.EXE als auch QuickBASIC bieten mit der ENVIRON$()-Funktion einen sauberen Weg an, um auf diese Informationen zugreifen zu können als auch Werte zu setzen.

Werte lesen

Eine sehr sinnvolle Anwendung davon ist die Verwendung des TEMP-Verzeichnisses von Windows. Damit Ihr BASIC-Programm auf jedem PC voll lauffähig wird, sollten Sie so etwas tunlichst vermeiden:

10 ' So besser nicht!
20 INPUT "Dateipfad und Gruppe, z.B. C:\DATEN\*.XLS"; PF$
30 SHELL "dir " + PF$ + " /b >C:\TMP\~TEMPDAT.TMP"
40 OPEN "C:\TMP\~TEMPDAT.TMP" FOR INPUT AS 1
50 WHILE NOT EOF(1)
60 LINE INPUT#1, D$
70 ' Datei D$ verarbeiten
80 WEND
90 CLOSE 1: KILL "C:\TMP\~TEMPDAT.TMP"
100 END

Der fatale Fehler: Es wird das Vorhandensein eines Laufwerkes C:\ vorausgesetzt mit einem Verzeichnis C:\TMP, was häufig nicht möglich und sinnvoll ist:

Aus all diesen Gründen sollten Sie dieser Variante den Vorzug geben:

10 ' So ist es korrekt!
20 RANDOMIZE TIMER
30 INPUT "Dateipfad und Gruppe, z.B. C:\DATEN\*.XLS"; pf$
40 TP$ = ENVIRON$("TEMP")
50 IF TP$<>"" THEN 110
60 PRINT "Die TEMP-Variable ist nicht gesetzt. Stellen Sie sicher, dass sich"
70 PRINT "in der Datei AUTOEXEC.BAT eine Zeile"
80 PRINT "SET TEMP=C:\TEMP"
90 PRINT "oder etwas ähnliches befindet."
100 SYSTEM
110 IF RIGHT$(TP$, 1) <> "\" THEN TP$ = TP$ + "\"
120 ' Möglichst einen eindeutigen Namen wählen, um Konflikte
130 ' zu vermeiden, wenn unter Windows (Multitasking!) dieses Programm
140 ' gleichzeitig mehrere Male aufgerufen wird
150 TP$ = TP$ + "~"
160 FOR I%=1 TO 3: TP$ = TP$ + CHR$(65 + CINT(INT(26! * RND))): NEXT I%
170 TP$ = TP$ + MID$(TIME$, 4, 2) + RIGHT$(TIME$, 2) + ".TMP"
180 SHELL "dir " + PF$ + " /b >" + TP$
190 OPEN TP$ FOR INPUT AS 1
200 WHILE NOT EOF(1)
210 LINE INPUT#1, D$
220 ' Datei D$ verarbeiten
230 WEND
240 CLOSE 1: KILL TP$
250 END

Anmerkung für UNIX- und Linux-Benützer: Bisher ist mir noch kein Weg bekannt, um eine eindeutige Prozessidentifikation wie $$ der Korn-Shell bestimmen zu können, aus diesem Grund wird mit Hilfe der Uhrzeit sowie des Zufallsgenerators versucht einen möglichst einmaligen Dateinamen zu erzeugen. Die Zeilen 150 bis 170 bilden also einen Ersatz für die in jedem UNIX- und Linux-Betriebssystem vorhandene tmpnam()-Funktion.

Umgebungsvariablen setzen

Beim Setzen von Umgebungsvariablen gilt bei DOS und Windows dieselbe Philosophie wie bei jedem UNIX und Linux:

Nur bei den Sohnprozessen kann die Umgebung gesetzt werden, nicht vom Vater. Dies sollte man speziell bei Programmen für die AUTOEXEC.BAT beachten!

Beispielszenario:

C:\BASICPRG>echo x%VAR1%x
xx

C:\BASICPRG>set VAR1=Andreas

C:\BASICPRG>echo x%VAR1%x
xAndreasx

C:\BASICPRG>gwbasic

GW-BASIC 3.23
(C) Copyright Microsoft 1983,1984,1985,1986,1987,1988
60300 Byte frei
Ok
print ">";environ$("VAR1");"< >";environ$("VAR2");"<"
>Andreas< ><
Ok 
environ "VAR2=Meile"
Ok
print ">";environ$("VAR2");"<"
>Meile<
OK
shell

Microsoft(R) Windows 98
   (C)Copyright Microsoft Corp 1981-1998.

C:\BASICPRG>echo x%VAR1%x%VAR2%x%VAR3%x
xAndreasxMeilexx

C:\BASICPRG>set VAR3=Hofen

C:\BASICPRG>echo x%VAR3%x
xHofenx

C:\BASICPRG>exit <= Sohnprozess endet
Ok
print ">";environ$("VAR1");"< >";environ$("VAR2");"< >";environ$("VAR3");"<"
>Andreas< >Meile< >< <= VAR3 existiert nicht mehr!
Ok
system <= Sohnprozess endet

C:\BASICPRG>echo x%VAR1%x%VAR2%x%VAR3%x
xAndreasxxx <= VAR2 existiert auch nicht mehr!

C:\BASICPRG>_

Erklärung: Exakt wie bei jedem UNIX und Linux üblich erstellt der exec-Systemaufruf von MS-DOS für den sog. Sohnprozess (engl. child process) eine vollständige Kopie von der Umgebungsvariablentabelle. Daher geht beim Beenden der Sohnprozesse mit exit bzw. system diese Kopie mit allen Änderungen jeweils verloren.


Wieder zurück zur Übersicht


© 2000 by Andreas Meile