Frage deutsch
~~~~~~~~~~~~~~
Wie erkennt mein BAS-Programm sein eigenes Verzeichnis?
Wie kann mein BAS-Programm erkennen, in welchem Verzeichnis es sich befindet - auch wenn es nicht im aktuellen Pfad liegt? Ich habe das Problem, dass mein Programm seine im selben Ordner liegenden Begleitdateien bei bestimmten Rechnerkonfigurationen nicht findet. Die Begleitdateien enthalten z.B. Sound, Grafik, Spielstände oder eine Highscore-Liste
 

Question English
~~~~~~~~~~~~~~
How can my -BAS programm figure out its own pathname?
How can my .BAS programm detect its own pathname - also if this ist not the actual path?
 

Antwort 1
~~~~~~~~
[ von Thomas Antoni, 11.1999 - 13.3.2006 ]
.
Dies ist eine Standardfrage, die sich fast jeder QBasic-Programmierer irgendwann einmal stellt. Die Frage taucht auf, sowie ein .BAS-Programm auf eine externe Datei zugreifen will, die sich in demselben Verzeichnis wie das Programm selbst befindet - z.B. Sound- und Grafikdateien. Befindet sich das BAS-Programm nicht in demselben Verzeichnis wie der QBasic-Interpreter QBASIC.EXE, so bleibt der aktuelle Pfad auf das QBASIC.EXE-Verzeichnis gesetzt. Das .BAS-Programm kann die externen Dateien daher nicht finden und es erscheint eine hässliche Fehlermeldung.
 
Eine weitere Schwierigkeit liegt darin, dass das QBasic-Programm ja nicht unbedingt im aktuell aktiven Pfad liegwn muss, sondern z.B. durch den folgenden Kommandozeilenaufruf gestartet weden kann:
c:\>qbasic\qbasic.exe basprogs\programm.bas
 
Dieser Aufruf erfolgt aus dem Stammverzeichnis "C:\" heraus, welches auch nach Start von qbasic.exe das aktive Verzeichnis bleibt.
 
Die Antwort lautet leider: Dies nur schwerlich möglich, da sich der QBasic-Interpreter sich den Pfadnamen des .BAS-Programms in einer lokalen Variablen merkt, deren Adresse nicht bekannt ist!!
 
Als Abhilfe kannst Du zum Aufruf Deines BAS-Programms ein Batchprogramm schreiben. Liegt z.B. der QBasic-Interpreter im Verzeichnis C:\QBASIC\ und Dein Programm im Verzeichnis C:\PROGS\, dann lautet die Batchdatei zum Aufruf Deines Programms MEINPROG.BAS:
C:
CD C:\PROGS
C:\QBASIC\QBASIC.EXE /RUN MEINPROG.BAS
 
Oder Du kompilierst Dein BAS-Programm zu einem EXE-Programm und verwendest den in den untenstehenden "Antworten" beschriebenen programmtechnischen Lösungen.
 
Andere Programmiersprachen bieten in dieser Hinsicht mehr Komfort.
 
 

Antwort 2
~~~~~~~~~~
[ von Pawel (
www.pkworld.de ) 1.2002 ]
.
Für eine EXE-Datei ist das aktuelle Verzeichnis der, von dem sie ausgeführt wird. Klickst Du die EXE direkt im Windows-Explorer an, ist das aktuelle Verzeichnis das Programmverzeichnis. Solltest Du aber z.B. eine Verknüpfung mit Deinem Programm auf dem Desktop erstellen, ist das Desktop (C:\WINDOWS\DESKTOP) das aktuelle Verzeichnis und es kann z.B. bei Dateizugriffen zu Fehlern kommen.
 
Vor langer Zeit habe ich (mit Unterstützung einiger anderer Programmierer) ein Modul entwicklet, der der aktuelle Pfad der EXE (Funktion PATHNAME$) und ihren eigenen Namen herausfindet (Funktion EXENAME$). Pathname ruft selber wiederum EXENAME$ auf. Hier ist der Code:
 
'************************************************************
' EXEPATH.BAS = Pfad und Namen der eigenen Programmdatei
' =========== ermitteln
' Dies Programm enthaelt die beiden Funktionen PATHNAME$
' und EXENAME$. PATHNAME$ ermittelt den Pfad des eigenen
' EXE-Programms und EXENAME$ den Dateinamen des eigenen
' EXE-Programms. PATHNAME ruft selber wiederum EXENAME$
' auf.
' Ablauffaehig unter QBasic und QuickBasic. QuickBasic
' 4.5 muss mit "QB /L" aufgerufen weden, da das Programm
' den CALL ABSOLUTE-Befehl verwendet.
'
' (c) Pawel (www.pkworld.de) 1.2002
'************************************************************
DECLARE FUNCTION EXENAME$ ()
DECLARE FUNCTION PATHNAME$ ()
'
CLS
'
PRINT EXENAME
PRINT PATHNAME
'
'------------ EXENAME$-----------------------------------------------
FUNCTION EXENAME$
DIM MCODE(1 TO 4) AS LONG, OS AS INTEGER, BX AS INTEGER, DUMMY AS LONG
DEF SEG = VARSEG(MCODE(1))
OS = VARPTR(MCODE(1))
POKE OS, &H55 'PUSH BP
POKE OS + 1, &H89: POKE OS + 2, &HE5 'MOV BP,SP
POKE OS + 3, &HB4: POKE OS + 4, &H62 'MOV AH,62
POKE OS + 5, &HCD: POKE OS + 6, &H21 'INT 21
POKE OS + 7, &H8B: POKE OS + 8, &H7E: POKE OS + 9, 6'MOV DI,[BP+6]
POKE OS + 10, &H89: POKE OS + 11, &H1D 'MOV [DI],BX
POKE OS + 12, &H5D 'POP BP
POKE OS + 13, &HCA: POKE OS + 14, 2: POKE OS + 15, 0'RETF 2
CALL ABSOLUTE(BX, OS)
DEF SEG = BX
ENVSM = PEEK(&H2C) + 256 * PEEK(&H2D)
ENVOS = 0
DEF SEG = ENVSM
DUMMY = 0&
WHILE DUMMY <> 65536
DUMMY = PEEK(ENVOS) + 256& * (PEEK(ENVOS + 1) + 256& * (PEEK(ENVOS + 2) + 256& * PEEK(ENVOS + 3)))
ENVOS = ENVOS + 1
WEND
ENVOS = ENVOS + 3
N$ = ""
A = 1
WHILE A <> 0
A = PEEK(ENVOS)
IF A <> 0 THEN N$ = N$ + CHR$(A)
ENVOS = ENVOS + 1
WEND
DEF SEG
EXENAME$ = N$
END FUNCTION
'------------ PATHNAME$ --------------------------------------------
'
FUNCTION PATHNAME$
FOR idx = LEN(EXENAME$) TO 1 STEP -1
IF MID$(EXENAME$, idx, 1) = "\" THEN EXIT FOR
NEXT idx
PATHNAME$ = LEFT$(EXENAME$, idx - 1)
END FUNCTION
 
Das obige Programm steht im Verzeichnis Progs\ zur Verfügung sowie online unter www.antonis.de/faq/progs/exepath.bas .
 
Einfach ins NOTEPAD kopieren und als BAS-Datei abspeichern. Beachte, dass das Programm CALL ABSOLUTE nutzt.
 
Wenn Du mit QB 4.5 arbeitest, musst Du daher die Entwicklungsumgebung mit dem Parameter /L QB laden. Die Datei QB.QLB (und QB.LIB zur späteren Kompilierung) muss natürlich im QB-Verzeichnis vorhanden sein.
 
 
*** Anmerkung von Thomas Antoni
Ich habe das obenstehende Programm ausprobiert. EXENAME$ und EXEPATH$ funktionieren prächtig, sogar unter Windows NT 4 . Für EXE-Programme, die mit QB erstellt wurden, hätten wir also eine Problemlösung . Für .BAS-Programme funktioniert das Ganze natürlich nicht, weil hier der Name "qbasic.exe" und der Pfadname der QBasic-Interpreters rückgemeldet wird, aber nicht derjenige des ablaufenden (interpretierten) BAS-Programms.
 
 

Antwort 3
~~~~~~~~~
[ von TT-Soft (
www.East-Power-Soft.de/ ) per Mail, 18.01.2002 ]
.
Wenn das Laufwerk bekannt ist, kann man den DIR-Befehl dazu benutzen. DIR mit der Option /S durchsucht einen ganzen Datenträger inklusive aller Unterverzeichnisse nach einer bestimmten Datei. Das Ergebnis dieser Suche muß nun noch in eine Temporäre Datei umgelenkt werden welche anschließend geöffnet und ausgelesen wird. Damit auch nur der Dateiname mit Pfadangabe in dieser Datei steht wird noch die Option /B eingefügt. Im Programm sieht das dann so aus:
 
FileName$ = "BEISPIEL.TXT"
SHELL "C:\" + FileName$ + " /B /S >c:\temp.tmp"
'
OPEN "c:\temp.tmp" FOR INPUT AS #1
INPUT #1, PathAndName$
CLOSE #1
KILL "c:\temp.tmp"
'
PRINT "Die Datei befindet sich im Pfad: ";PathAndName$
 
Probleme bekommt man nur wenn die Datei bzw. eine andere mit gleichem Namen, mehrmals auf dem Laufwerk vorhanden ist. Dann würde man nämlich nur die erste gefundene auslesen. Ebenfalls prüft diese Routine nicht ob die Datei überhaupt gefunden wurde. In diesem Fall wäre PathAndName$ = "".
 
 

Antwort 4
~~~~~~~~~~~~~~~~~
[ per E-Mail von von Urs Langmeier, 31.1.02 ]
 
Zu "Wie schreibe ich BAS-Programme (mit Begleitdateien), die in jedem Pfad laufen ?" habe ich für Dich ein paar Inputs, die du, wenn willst, gebrauchen kannst.
 
Nicht zu vergessen ist hier die Möglichkeit, ein festes Verzeichnis zu verwenden, wie das zum Beispiel in LaOS der Fall ist. Alle Dateien sind dort immer unter C:\LAOS\. Einige User sind aber mit dieser Methode nach meiner Erfahrung nicht sehr zufrieden, obwohl es ihnen eigentlich nicht schadet.
 
Die Möglichkeit der Umgebungsvariable in Autoexec.bat ist etwas kompliziert für den Programmierer, und ich persönlich als User respektiere diese Methode nicht mehr, weil man den Computer nach der Installation neu starten muss. Für ein Basic-Programm das ich testen will ein bisschen ein grosser
(Zeit-)'Aufwand'.
 
Eine andere Methode ist es, ein Installationsprogramm zu machen, das im Root C:\ eine Datei einrichtet, worin das Installationsverzeichnis hineingeschrieben wird. Das Basic-Programm muss dann nur noch den Pfad aus der Datei auslesen, um zu wissen, wo sich die Begleitdateien befinden. Diese Methode ist durchaus berechtigt. In Windows 95 wird die Pfad-Information vermutlich in MSDOS.SYS publiziert.
 
Alles Gute,
Urs
www.laosoft.ch/ichmagdich
 
 

Antwort 5
~~~~~~~~~~~~~~~~~
[ von Thomas Antoni, 18.10.2002 - 12.11.2002 ]
 
*** Problem
Wie findet mein BAS-Programm seine Begleitdateien?
 
Jeder QBasic-Programmierer stößt irgendwann auf das Problem, dass ein BAS-Programm seine Text- Sound- oder Grafik- Begleitprogramme nur dann findet, wenn diese sich in demselben Verzeichnis befinden wie die QBasic-Entwicklungsumgebung QBASIC.EXE selber. Nicht immer liegt das BAS-Programm im momentan gerade aktuellen Verzeichnis, welches man bequem ermitteln könnte, z.B. mit SHELL "CD > tmp.txt". Ruft man das BAS-Programm aus der QBasic-Entwicklungsumgebung heraus auf, so liefert SHELL "CD > tmp.txt" den Pfad der QBasic-Entwicklungsumgebung und nicht denjenigen der BAS-Datei.
 
Im Gegensatz zum EXE-Programm gibt es für ein BAS-Programm prinzipiell leider keinerlei Möglichkeit, seinen eigenen Pfad herauszufinden.
 
Besonders kritisch wird es, wenn der Programmierer sein BAS- Programm weitergeben will, z.B. über das Internet.
 
In ihrer Not greifen viele Programmierer zu irgendwelchen hakeligen, selbstgebastelten Installationsroutinen oder packen die Entwicklungsumgebung QBASIC.EXE zum Download-Archiv dazu.
 
Kannst Du mir eine Lösung für dieses Problem nennen?
 
*** Lösung
Die einfachste Lösung für dieses Problem besteht darin, dem Anwender ein Kopieren aller Dateien in ein festes Verzeichnis, z.B. C:\MEINPROG\ zu empfehlen.
 
Wenn der Anwender wider Erwarten doch ein anderes Verzeichnis wählen will, so kann man ihm dies erleichtern, indem man ganz vorne im BAS-Programm den Pfadnamen in eine Variable einträgt. Der Anwender braucht dann nur noch diese Wertzuweisung an seinen tatsächlichen Pfad anzupasen und muss nicht an x Stellen im Code diese Änderung durchführen.
 
Der entsprechende Befehl könnte etwa so aussehen:
'---- Tragen Sie bei Bedarf im untenstehenden Befehl den aktuellen Pfad
'---- ein, wenn sich das Programm in einem anderen Verzeichnis befindet
path$ = "C:\MEINPROG\"
 
Noch komfortabler ist es, dem Anwender das Ändern des Quellcodes zu ersparen und gleich vorn im Programm über einen Dialog den Namen des aktuellen Verzeichnisses zu erfragen. Als vorbesetzten Pfad könnte dieser Dialog am besten gleich "C:\MEINPROG\" anbieten, so dass der Anwender im "Normalfall" nur mit der Eingabetaste bestätigen muss.
 
Einen Programmvorschlag für die Komfort-Version findest Du nachstehend:
 
'****************************************************************************
' READFILE.BAS - Lesen aus einer externen Textdatei
' ============
' Dieses Q(uick)Basic-Programm demonstriert, wie man aus einem BAS-Programm
' heraus ohne Fehler auf eine externe Begleit-Datei, in diesem Falle
' "text.txt", zugreifen kann, die sich in demselben Verzeichnis wie die
' BAS -Datei befindet. Der Pfadname wird vom Anwender sooft erfragt bis die
' Datei ohne Fehler lesbar ist.
'
' (c) Thomas Antoni, 18.10.2002 - 4.4.2006
'****************************************************************************
'
ON ERROR GOTO ErrorHandler 'Bei nicht vorhandenem Pfad
'Fehlerroutine anspringen
Start: 'Einsprungstelle bei nicht vorhandenem Pfad
CLS
IF Fehler% = 0 THEN
path$ = "C:\READFILE\" 'Vorbesetzter Ordner fuer die Begleitdateien
ELSE 'Fehler aufgetreten
COLOR 12, 0 'rot auf schwarz
LOCATE , 5
PRINT "Pfad exististiert nicht, bitte richtigen Pfad eingeben!"
COLOR 7, 0 'wieder normale Schrift hellgrau auf schwarz
END IF
'
'------------- Aktuellen Pfad erfragen und in path$ hinterlegen -------------
LOCATE 3, 5
PRINT "In welchem Verzeichnis befindet sich das Programm?"
LOCATE 7, 5
PRINT "Editieren [Rueck-Taste] Uebergabe [Enter] Beenden [Esc]"
COLOR 15, 3 'weiss auf tuerkis
LOCATE 5, 5
PRINT SPC(70); 'Eingabefeld tuerkis anzeigen
key$ = ""
LOCATE , 5
PRINT path$; 'Vorbesetzten Pfad anzeigen
LOCATE , , 1 'Cursor anzeigen
DO
SELECT CASE key$
CASE CHR$(13): EXIT DO 'Eingabetaste -> Ende der Eingabe
CASE CHR$(27): END 'Esc -> Programm beenden
CASE CHR$(8) 'Backspace-Taste
IF LEN(path$) > 0 THEN 'Falls Textlaenge > 0 ...
path$ = LEFT$(path$, LEN(path$) - 1) '... Text um 1 Zeichen kuerzen
END IF
CASE CHR$(29) TO CHR$(255) 'alfanumerisches Zeichen?
path$ = path$ + key$ 'Tastenzeichen anfuegen
END SELECT
LOCATE , 5: PRINT SPACE$(LEN(path$) + 1); 'alten Text loeschen
LOCATE , 5: PRINT path$; 'Neuen Text anzeigen
LOCATE , , 1 'Cursor anzeigen
DO: key$ = INKEY$: LOOP WHILE key$ = "" 'Warten bis Taste betaetigt
LOOP
COLOR 7, 0 'wieder hellgrau auf schwarz
IF RIGHT$(path$, 1) <> "\" THEN path$ = path$ + "\" 'Backslash anhaengen
'falls erforderlich
'
'----------- Datei text.txt oeffnen + deren erste Zeile auslesen ------------
LOCATE 8, 20
Fehler% = 0 'Vorbesetzung: Kein Fehler
OPEN path$ + "text.txt" FOR INPUT AS #1
IF Fehler% = 0 THEN
LOCATE 11, 5
PRINT "Der Pfad ist korrekt eingegeben. Er lautet "; path$
PRINT
LINE INPUT #1, text$
LOCATE 13, 5
PRINT "Die 1. Zeile der Datei lautet:"
LOCATE , 5
PRINT text$
SLEEP 'Warten auf beliebige Taste
END IF
CLOSE #1
END
'
'----------- Fehlerbehandlung falls Pfad nicht vorhanden -------------------
ErrorHandler:
Fehler% = 1 'Fehlermerker setzen
RESUME Start 'neue Eingabe
 
 
Das obige Programm steht zusammen mit der Beispiel-Begleitdatei text.txt als ZIP-Archiv im Pfad Progs\readfile.zip zur Verfügung sowie online unter www.antonis.de/faq/progs/readfile.zip .
 
 
*** Hinweis zu EXE-Programmen
Bei kompilierten EXE-Programmen kann man den Pfadeingabe-Dialog weglassen, da das Verzeichnis, in dem sich das Programm befindet meist auch das aktuell gültige Verzeichnis ist. Nur in "exotischen" Fällen wird das Programm aus einem anderen Verzeichnis heraus aufgerufen werden, z.B. durch "C:\>MEINPROG\MEINPROG.EXE" . Aber auch soche Spezielfälle kann man bei EXE-Programmen absichern; siehe unter "Dateien, Verzeichnisse und Laufwerke bearbeiten -> Wie erkennt mein BAS- Programm sein eigenes Verzeichnis?"
 
 
 

Antwort 6
~~~~~~~~~~~~~~~~~
[ von Helium im QB-Forum, 11.11.2002 ]
.
Da keiner diese Information hat, kann man Sie leider nicht per Programm beschaffen.
 
Man kann zwar fragen, welche Datei DOS grade ausführt, und das ist der QBasic-Interpreter. Aber niemand weiß, welche Datei grade interpretiert wird. Vor allem kann man das mit CHAIN ja auch noch während der Ablaufzeit beliebig ändern.
 
Der einzige, der weiß, welche BAS-Datei grade interpretiert wird ist der Interpreter. Und der sagt es einem natürlich nicht, da, wenn man das Programm compilieren würde, kein Interpreter mehr da wäre, den man fragen könnte.
 
Ich würde einfach immer eine compilierte Version Deines Programms bereit stellen. Die kann ihren eigenen Pfad bestimmen.
 
 
 

Antwort 7
~~~~~~~~~~~~~~~~~
[ von JaWa (
JanekWalkenhorst*Lycos.de ) im QB-Forum, 12.3.03 ]
 

Wie findet mein Programm seine INI-Datei
Bei meinen Programmen mach ich dass immer so, dass ich davon ausgehe, dass die Datei im aktuellen Verzeichnis ist, und wenn nicht (Irgendein Fehler beim Lesen) dann mach ich ne neue (Standarteinstellungen) und sage dem Benutzer, dass eine neue Datei angelegt wurde und er das Programm neu konfiguieren muss.
Wow! Dass war nur ein Satz!
JaWa
 
 
 

Antwort 8
~~~~~~~~~~~~~~~~~
[ von greenbit (
info*greenbit.ch - www.greenbit.ch ) im QB-Forum, 12.3.03 ]
 
Diese FUNCTION gibt den kompletten String (z. B. "c:\qbasic\beispiel.exe") zurück. Sie funktioniert ab QB 4.5, das mit der Option /L gestartet werden muss.
 
 
'$INCLUDE: 'qb.bi'
FUNCTION exename$
DIM regs AS RegType
regs.ax = &H6200
CALL INTERRUPT(&H21, regs, regs)
DEF SEG = regs.bx
DEF SEG = PEEK(&H2C) + 256 * PEEK(&H2D)
i = 0
DO
i = i + 1
LOOP UNTIL PEEK(i) = 0 AND PEEK(i - 1) = 0
i = i + 3
tempexename$ = ""
DO
IF PEEK(i) <> 0 THEN tempexename$ = tempexename$ + CHR$(PEEK(i)) ELSE EXIT DO
i = i + 1
LOOP
exename$ = tempexename$
END FUNCTION
 
 
 
 

Antwort 9
~~~~~~~~~~~~~~~~~
[ von Thomas Antoni, 18.3.2004 ]
 
Da gibt es die folgende, sehr schöne Routine "ExeName" von dem berühmten QuickBASIC-Guru Ethan Winer.
 
'********************************************************************
' EXENAME.BAS - Example for determining the own name and path
' =========== Zeigt wie ein Programm seinen eigenen Namen und Pfad
' ermitteln kann
'
' This program shows how to figure out the path from which your
' program has been run. This is useful when you need to open a data
' file, but your program may have been run by adding the path
' explicitly and thus you can't count on that being the current
' directory. So even your program was run using C:\PATH\PROGRAM you
' can still determine what "PATH" is and also if your program was
' renamed. Note that when run in the BASIC editor, it is the editor
' whose name is reported!
'
' Attentention: This programm cannot be run with QBasic but unly with
' ~~~~~~~~~~~~ QuickBASIC 4.5 and 7.1. The reason ist the use of the
' CALL INTERRUPT statement.
'
' (c) Ethan Winer
'********************************************************************
'
DEFINT A-Z
DECLARE FUNCTION ExeName$ ()
'$INCLUDE: 'QB.BI' 'use QBX.BI with BASIC 7, or VBDOS.BI with VB/DOS
'needed for CALL Interrupt used inside ExeName
MyName$ = ExeName$
'---- isolate the path and file names
'
CLS
FOR X = LEN(MyName$) TO 1 STEP -1
Char = ASC(MID$(MyName$, X, 1))
IF Char = 58 OR Char = 92 THEN ' ":" or "\"
Path$ = LEFT$(MyName$, X)
File$ = MID$(MyName$, X + 1)
EXIT FOR
END IF
NEXT
'
PRINT "The path name is: "; Path$
PRINT "The file name is: "; File$
'
FUNCTION ExeName$
'ExeName returns the name of the currently running program.
'It requires DOS 3.0 or later.
DIM Regs AS RegType 'for CALL Interrupt
'
'Int 21h function 62h returns the PSP segment in BX.
Regs.ax = &H6200
CALL Interrupt(&H21, Regs, Regs)
'
'The environment segment is at address 44/45 in the PSP segment.
DEF SEG = Regs.bx
DEF SEG = PEEK(44) + PEEK(45) * 256
'
'Search the environment segment for two zero bytes in a row. The
'program name follows the two bytes that follow the two zeros.
Byte = 0
DO
IF PEEK(Byte) = 0 THEN 'this is zero
IF PEEK(Byte + 1) = 0 THEN 'this is too
Byte = Byte + 2 'so skip both
EXIT DO 'we be done
END IF
END IF 'else,
Byte = Byte + 1 'keep looking
LOOP
IF PEEK(Byte) = 1 THEN 'if this byte = 1
Byte = Byte + 2 'the name follows
DO WHILE PEEK(Byte) 'up to another zero
Temp$ = Temp$ + CHR$(PEEK(Byte))
Byte = Byte + 1
LOOP
ExeName$ = Temp$ 'assign the function output
END IF
DEF SEG 'restore default
END FUNCTION
 
Das obige Programm steht im Verzeichnis Progs\ zur Verfügung sowie online unter www.antonis.de/faq/progs/exename.bas .
 
Ethan's Webseite
www.ethanwiner.com ist übrigens sehr empfehlenswert, besonders die Rubrik "magazine articles"
 
 

Answer 10
~~~~~~~~~
[ by Ethan Winer, 18.3.2004 ]
My following program ExeName shows how to tell the path from which your program has been run. This is useful when you need to open a data file, but your program may have been run by adding the path explicitly and thus you can't count on that being the current directory. So even your program was run using C:\PATH\PROGRAM you can still determine what "PATH" is and also if your program was renamed.
 
ExeName ist available in the above "Antwort 9" and on my website
www.ethanwiner.com in the "magazine articles" section.
 
 

Answer 11
~~~~~~~~~~
[ by Paul Sullivan, Nov 23, 1991 ]
 
*** Answer English
This program will read the environment to find the TRUE file name of the actually executed EXE-file - not just the name but the PATH in which it was executed from. You can use it for QuickBASIC programs compiled with QB 4.5 and 7.1.
 
*** Antwort deutsch
Mein untenstehenden QuickBASIC-Programm PATHNAME ermittelt den Pfadnamen und den Dateinamen des gerade ausgefuehrten EXE-Programms. Wenn Du diese Programm z.B. zu der ausfuerhrbaren Datei PATHNAME.XE kompilierst und im Laufwerk C: im Verzeichnis "Test" ablaufen laesst, dann wird "C:\Test\PATHNAME.EXE" zurueckgemeldet.
 
*** Program PATHNAME.BAS
 
'***************************************************************
' PATHNAME.BAS = Retrieves path and filename of the actually
' =========== executed compiled QB Program
' Ermittelt Pfad und Dateinamen des gerade ausge-
' gefuehrten mit QB compilierten EXE-Programms
'
' Deutsche Beschreibung
' -----------------------
' (von Thomas Antoni, 14.3.2006)
' Dieses QuickBASIC-Programm ermittelt den Pfadnamen und den
' Dateinamen des gerade ausgefuehrten EXE-Programms. Wenn Du
' diese Programm z.B. zu der ausfuerhrbaren Datei PATHNAME.XE
' kompilierst und im Laufwerk C: im Verzeichnis "Test" ablaufen
' laesst, dann wird "C:\Test\PATHNAME.EXE" zurueckgemeldet.
' Im Interpeter-Modus meldet das Programm den Pfadnamen der
' QuickBASIC-Entwicklungsumgebung zurueck, also z.B.
' "C:\BASIC\QB.EXE". Das Programm ist unter QuickBASIC 4.5 und
' 7.1 ablauffaehig, nicht jedoch unter QBasic, weil der
' Befehl CALL Interrupt verwendet wird. Aus demselben Grund
' muss QuickBASIC mit der Option "/L" gestartet werden, also
' z.B. mit "QB.EXE /L PATHNAME.BAS". Bei QB 7.1 muss der Name
' der .BI-Datei angepasst werden; siehe unten im Listing.
'
' English Description
' -------------------
' This program will read the environment to find the TRUE file
' name of the actually executed EXE-file - not just the name,
' but the PATH in which it was executed from. You can use it
' for QuickBASIC programs compiled with QB 4.5 and 7.1.
' When intepreted, the program will deliver' the path and filename
' of the QB IDE .
'
'(c) by Paul Sullivan, Nov 23, 1991
'****************************************************************
'
'
REM *************************************************************
REM ** **
REM ** This program will read the TRUE program name from the **
REM ** Environment. If you are executing a program called **
REM ** HELLO.EXE, and only typed HELLO at the command line, **
REM ** It would return the ENTIRE PATH of where HELLO.EXE is **
REM ** located. If HELLO.EXE is in C:\DOS\BASIC\QB, the **
REM ** line returned from this program would be **
REM ** c:\dos\basic\qb\HELLO.EXE instead of just HELLO **
REM ** **
REM ** This program is basically a reprint from a very early **
REM ** Cobb Inside Microsoft Basic Journal, but can be used **
REM ** freely. It is in the Public Domain. No credit or **
REM ** other compensation is necessary or expected. **
REM ** **
REM ** This program should work with BOTH QuickBasic 4.5 and **
REM ** the Basic Professional Development System 7.xx **
REM ** **
REM *************************************************************
REM **** Below is the main program module ************
DECLARE FUNCTION ProgramName$ ()
DEFINT A-Z
CONST FALSE = 0
CONST TRUE = -1
'
'PDS users should change the next line to include the QBX.BI file
'$INCLUDE: 'QB.BI'
'
CLS
PRINT "Program name = "; ProgramName$
SLEEP
END
'
REM **** Below is a FUNCTION that should be parsed by the QB ***
REM **** or QBX Environments. *********************************
'=================== Function ProgramName$ ======================
'== INPUT: None ==
'== RETURNS: Name of currently executing program ==
'================================================================
'
FUNCTION ProgramName$
DIM Regs AS RegType
'
'Get PSP address
'
Regs.ax = &H6200
CALL Interrupt(&H21, Regs, Regs)
PSPSegment = Regs.bx
'
'Find environment address from PSP
'
DEF SEG = PSPSegment
EnvSegment = PEEK(&H2D) * 256 + PEEK(&H2C)
'
'Find the filename
'
DEF SEG = EnvSegment
EOT = FALSE 'Set end of environment table flag
Offset = 0
WHILE NOT EOT
Byte = PEEK(Offset) 'Get table character
IF Byte = 0 THEN 'End of environment string?
' PRINT 'Uncomment to print environment
Offset = Offset + 1
Byte = PEEK(Offset)
IF Byte = 0 THEN 'End of environment?
Offset = Offset + 3 'Yes - Skip over nulls & tbl info
C% = PEEK(Offset)
WHILE C% <> 0 'Assemble filename string
FileN$ = FileN$ + CHR$(C%) ' from individual
Offset = Offset + 1 ' characters
C% = PEEK(Offset)
WEND
EOT = TRUE 'Set flag to exit while/wend loop
END IF
ELSE 'No-Read more environment string
' PRINT CHR$(Byte); 'Uncomment to print environment
Offset = Offset + 1
END IF
WEND
ProgramName$ = FileN$
DEF SEG
END FUNCTION
 
Das obige Programm PATHNAME.BAS und die kompilierte Datei PATHNAME.EXE stehen Verzeichnis Progs\ zur Verfügung sowie online unter www.antonis.de/faq/progs/pathname.bas und www.antonis.de/faq/progs/pathname.exe .
 
 

[ The QBasic-MonsterFAQ --- Start Page: www.antonis.de/faq ]