Sebastian Administrator
Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 15.10.2004, 13:42 Titel: Verzeichnis herausfinden |
|
|
Hallo.
Die MonsterFAQ hat Folgendes geschrieben: | Frage deutsch
~~~~~~~~~~~~~~
Wie kann mein BAS-Programm erkennen, in welchem Verzeichnis es sich befindet - auch wenn es nicht im aktuellen Pfad liegt?
Question English
~~~~~~~~~~~~~~
How can my .BAS programm detect its own pathname - also if this ist not the actual path?
Antwort 1
~~~~~~~~
[ von Thomas Antoni, 11.1999 - 19.6.2002 ]
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äßliche Fehlermeldung.
Eine weitere Schwierigkeit liegt darin, dass das QBasic-Programm ja nicht unbedingt im aktuell aktiven Pfad leiegn 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 ist nicht 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 un d wendest den in "Antwort 2" beschriebenen Trick an.
Antwort 2
~~~~~~~~~~
[ von Pawel ( http://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
'Dies Programm enthält die beiden Funktionen PATHNAME$
'und EXENAME$. PATHNAME$ ermittelt den Pfad des eigenen
'Programms und EXENAME$ den eigenen Dateinamen.
'PATHNAME ruft selber wiederum EXENAME$ auf.
'Ablauffähig unter QBasic und QuickBasic. QuickBasic 4.5
'muss mit "QB /L" aufgerufen weden, da das Programm
'den CALL ABSOLUTE-Befehl verwendet.
'Von Pawel (www.pkworld.de) 1.2002
'======================================================
DECLARE FUNCTION EXENAME$ ()
DECLARE FUNCTION PATHNAME$ ()
'
CLS
'
PRINT EXENAME
PRINT PATHNAME
'
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
'
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
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 ihn mit dem Parameter /L QB laden. Die
Datei QB.QLB (und QB.LIB zur späteren Kompilierung) sollte 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$ = "". |
Viele Grüße!
Sebastian _________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|