Autor | Thema: API aber wie? | | Datum:16.07.02 12:28 
(risikowks@web.de) | |
Ich möchte per Programm einen File suchen;
natürlich auch in Unterdirectories, und schnell.
Also warum nicht per API denke ich? und los.
window 0,0-500,500
declare str#,data#
dim str# ,100
dim data# ,100
Def FindFirstFile(2) !"KERNEL32","FindFirstFileA"
string str#,0="c:\Config.sys"
print findfirstfile (str#,data#)
print @string$ (data#,0)
waitinput
dispose str#
dispose data#
Enttäuschung: In Data# steht nur eine Zahl, oder Müll wenn der File nicht da ist. Und Unterdirectories werden garnicht durchsucht.
Also, So! gehts nicht; aber wie ???
Ich muß noch viel lernen
kann Jemand helfen?
Walter Köhler
|
| | Datum:16.07.02 14:11 
(joerse@gmx.de) | |
'Hallo Walter,
'So findet man Dateien auch in Unterverzeichnissen.
'Bei der Suche nach mehreren Dateien (mit gleichem Namen) muß man die Suche
ab erster Fundstelle + 1 'wiederholen.
Def CharUpperBuff(2) !"USER32","CharUpperBuffA"
Def CharLowerBuff(2) !"USER32","CharLowerBuffA"
Cls
declare Suchstring$,b#,Position&,Size&
Proc Suche
Parameters s$,p&
WhileNot Suchstring$ = ":"
Suchstring$ = Char$(b#,Position&,1)
Position& = Position& - 1
Wend
EndProc
ChDir "C:\\"
Addfiles *"*.*"
Size&=%getcount * 256
Dim b#,Size&'Sollte reichen da Pfade max. 256 haben können
MoveListToMem(b#,Chr$(0))
CharUpperBuff(b#,Size&)
Suchstring$=Upper$("UrlTrenner")
Position&=Mempos(b#,0,Suchstring$)
If Position& >= 0
Suche Suchstring$,Position&
Else
Print Suchstring$,"nicht gefunden"
EndIf
Print String$(b#,Position&)
Print FindFirst$(String$(b#,Position&))'um nochmal die korrekte Schreibweise
'zu haben
WaitInput
Gruß
Jörg
|
| | Datum:16.07.02 14:23 
(rgh-soft@t-online.de) | |
Hallo,
Du hast es fast richtig gemacht. Jedoch ist in data# nicht nur der Dateiname, sondern auch weitere Infos über die gefundene Datei. Der Dateiname beginnt an Position 44 in dieser Struktur. Das Ergebnis der API-Funktion ist das Dateihandle bei Erfolg und ansonsten -1. Bei -1 wurde keine Datei gefunden und dann ist der der Inhalt von data# unbestimmt, also in der Regel irgendwelcher Müll! So funktioniert es:
window 0,0-500,500
declare str#,data#,dateihandle&
dim str# ,100
dim data# ,100
Def FindFirstFile(2) !"KERNEL32","FindFirstFileA"
string str#,0="c:\Config.sys"
dateihandle& = findfirstfile (str#,data#)
print "Ergebnis: " + @str$(dateihandle&)
print "DATA: " + @string$(data#,44)
waitinput
dispose str#
dispose data#
Hinweis: Das Handle habe ich vor dem Ausdruck zwischengespeichert, da ein bislang nicht gefundener Bug beim Printbefehl oftmals das Zeilenende verschluckt, wenn man eine definierte Funktion direkt im PRINT-Befehl stehen hat.
Noch eleganter wird es, wenn man die mitgelieferten Header-Dateien (ab PROFAN 7) benutzt. Die API-Funktionen finden sich in WINDOWS.PH und die Strukturen in STRUCTS.PH. Wir benötigen hier die Struktur WIN32_FIND_DATA (siehe API-Hilfe) zur Aufnahme der Daten über die Datei:
$H windows.ph
$H structs.ph
window 0,0-500,500
declare str#,data#,dateihandle&
struct Daten = ~WIN32_FIND_DATA
dim str#,100
dim data#,Daten
string str#,0="c:\Config.sys"
dateihandle& = ~FindFirstFileA(str#,data#)
print "Ergebnis: " + @str$(dateihandle&)
print "DATA: " + data#.cFileName#
waitinput
dispose str#
dispose data#
Mit struct erzeugen wir eine Struktur "Daten", die die entsprechenden Elemente enthält. Mit dim weisen wir der Bereichsvariable "data#" diese Struktur zu. Der Dateiname der gefundenen Datei findet sich nach dem Aufruf im Element "cFileName#".
Gruß
Roland
|
| | Datum:15.09.02 14:03 
(sumatra@dhjt.de) | |
Hallo Roland,
die config.sys findet sich ja leicht, ABER:
wie ist das, wenn ich in einem x-beliebigen Unterverzeichnis eine Datei habe und den kompletten Pfad wissen will? Geht das auch so schön schnell?
Viele Grüße
Hans-Jürgen
|
| | Datum:16.09.02 08:58 
(rgh-soft@t-online.de) | |
Hallo Hans-Jürgen,
leider kenne ich dafür keine API-Funktion. Das muß man mehr oder weniger "zu Fuß" machen.
Zunächst kann man Wildcards einsetzen und weitere Dateien suchen mit FindNextFileA:
$H windows.ph
$H structs.ph
window 0,0-500,500
declare str#,data#,dateihandle&,ok&
struct Daten = ~WIN32_FIND_DATA
dim str#,100
dim data#,Daten
string str#,0="C:\\*.*"
dateihandle& = ~FindFirstFileA(str#,data#)
if dateihandle& >= 0
print "DATA: " + data#.cFileName#
ok& = 1
while ok& = 1
ok& = ~FindNextFileA(dateihandle&,data#)
print "DATA: " + data#.cFileName#
endwhile
else
print "Nicht gefunden."
endif
waitinput
dispose str#
dispose data#
(Hinweis: Man kann natürlich auch die PROFAN-Versionen der Funktionen (FindFirst, FindNext) verwenden!)
Bei "*.*" werden auch die Verzeichnisse gefunden. Ob ein Name nun Datei oder Verzeichnis ist lest sich mit GetFileAttributes ermitteln. Bei Verzeicnissen müßte man nun rekursiv weiter in die Tiefe gehen, dort wieder alle Dateien auflisten, .... und genau das macht der PROFAN-Befehl ADDFILES mit *.
Gruß
Roland
|
| | Datum:16.09.02 09:27 
| |
Hallo,
doch, so eine API gibt es tatsächlich:
GetFullPathName() aus der Kernel32 macht das, was du suchst.
Gruß, Frank
|
| | Datum: 16.09.02 10:12 
(rgh-soft@t-online.de) | |
Danke, Frank!
Wenn man die gesuchte Datei auf den von mir beschriebenen Weg gefunden hat, kann man mit dieser Funktion in der Tat den kompletten Pfad zu dieser Datei ermitteln. Diese Funktion fügt das aktuelle Laufwerk, das aktuelle Verzeichnis und den übergebenen Dateinamen zum kompletten Dateinamen mit Pfad zusammen. (Es wird nicht überprüft, ob es die Datei wirklich gibt.)
Einen API-Aufruf, der die rekursive Suche auch in kompletten Verzeichnisbäumen erledigt, gibt es meines Wissen leider nicht. (Ich lasse mich allerdings gerne eines Besseren belehren!)
Gruß
Roland
|
|
|