>>>Hi,people
>>>I need to find file somewhere on a harddrive.
>>>I have filename and drive (c: or e:)
>>>I want to use API FindFirstFile to find this file.
>>>How can i present WIN32_FIND_DATA structute which this API require?
>>>Thank you
>>
>>Alex,
>>
>>Just to expand on what Houston said, if you do not provide FindFirstFile() with a complete path, it only searches the current working directory. In the case of using it within VFP, you'd have to re-set this via SET DEFAULT. This is the same as you'd have to do with ADIR(), if you only wish to retrieve folders (directories) for example.
>>
>>It does have the ability, like ADIR(), to utilize wildcards. The Scripting.FileSystemObject, however, has no facility to filter out undesired files using wildcards.
>>
>>About the closest you can get is the Shell.Application object's FindFile method. This presents the same dialog that the Windows Explorer does. While it can be instantiated programmatically from within VFP, there is no programmatic control (such as setting the drive) over it, and no way to programmatically retrieve the result set. Further, determining if it is even available is a two step process. First, you have to check the registry for the presence of the ProgID under HKEY_CLASSES_ROOT, then, if present, check the DLL (Shell32.dll) to assure that the version is greater than or equal to 4.71. Getting it installed, if not present can be difficult. It was an optional part of IE 4.01 (it installs with the Active Desktop), but not later versions. It's not part of Win 95, but is in Win 98 and above.
>>
>>This does have some utility from with the VFP development environment, however. It's a better version of Filer than we had in the past. You can simply instantiate the object from the Command window, set your search criteria and drag any of the files returned into the Command window. They will then automatically open in the appropriate designer. This applies, of course, to those files that VFP opens natively.
>Thank you guys.
>I already realized that API FindFirstFile will not help me. I wrote my own recursive function with ADIR() and it works fine.Only one complication:
>every time when i call my function in recursive loop i need to create new array for ADIR() function and later release this array.It works but it does not look nice.
>Alex
>ADIR() function
Hi Alex,
I found two functions in my commonWg library, which I got from here. The first one, I believe, belongs to Mike Helland (for some reason, I didn't put description here, as I usually do):
procedure FILEFIND
lparameters pcFile, CUR_DIR
wait window nowait 'Searching file '+ pcFile
filefound = " "
if right((CUR_DIR),1) = "\"
CUR_DIR=substr(CUR_DIR,1,len(CUR_DIR)-1)
endif
=filesrch(pcFile,CUR_DIR)
if empty(filefound)
filefound = "FILE NOT FOUND!"
endif
wait clear
return upper(filefound)
function filesrch
parameter FILENAME, curdir
private FILENAME, curdir, temp_dir, i, j
dimension temp_dir(1,1)
temp_dir(1,1)=" "
=adir(temp_dir,curdir+"\"+FILENAME)
if ascan(temp_dir,upper(FILENAME)) != 0
filefound=curdir + "\"+ upper(FILENAME)
return to FILEFIND
endif
=adir(temp_dir,curdir+"\*.","D")
if temp_dir(1,1) != " " and filefound =" "
if temp_dir(1,1)="."
if alen(temp_dir,1)=2
return
endif
i=3
else
i=1
endif
for j = i to alen(temp_dir,1)
curdir=curdir+"\"+temp_dir(j,1)
=filesrch(FILENAME,curdir)
curdir=substr(curdir,1,rat("\",curdir)-1)
endfor
endif
return
The second is by Houston Brennan and it would work, but it used Filer, so it's not distributable:
lparameters tcFileToSearch, tcSearchPath, tlEntireNetwork
if vartype(m.tcFileToSearch)<>'C' or empty(m.tcFileToSearch)
return .f. && First parameter is required
endif
#define NoAttributesSet 0
#define readonly 1
#define hidden 2
#define system 4
#define Archived 32
#define DoNotSearchSubFolder 0
#define SearchSubFolder 1
local lcRetPath, lcDrive, lcSearchPath, lnStartTime,;
lcPrevOnEsc, lcPrevEscape, MsgTail, halt, loFiler
lcRetPath=''
lnStartTime = seconds() && # seconds since midnight
lcPrevOnEsc = on('escape') && save previous Escape handler
lcPrevEscape = set('escape') && previous Escape enablement state
set escape on && enable escape handling
halt = .f. && allow loop to run until this flag is toggled
on escape halt = .t. && force immediate termination if user escapes
MsgTail = "... Wait or press Esc to cancel ..."
wait window nowait 'Searching file '+m.tcFileToSearch+iif(m.tlEntireNetwork,' in the whole network...',' ...')
loFiler = createobject( "Filer.FileUtil" )
loFiler.FileExpression = m.tcFileToSearch
loFiler.SubFolder = SearchSubFolder && Search all tree
if vartype(m.tcSearchPath)<>'C' or (empty(m.tcSearchPath) and !m.tlEntireNetwork)
lcSearchPath='c:\' && Local drive
else
lcSearchPath=m.tcSearchPath
endif
if !tlEntireNetwork && Only specified path to search
loFiler.SearchPath = m.lcSearchPath
set message to 'Searching in '+m.lcSearchPath + m.MsgTail
loFiler.find(0) && Perform search
if m.halt or lastkey()=27 && Escape was pressed
exit
endif
if loFiler.files.count>0 && At least one file was found, pick up the first
lcRetPath=loFiler.files.item[1].path
endif
else
local lni, lcDrive
for lni = 67 to 90
lcDrive = chr(m.lni)
if inlist(drivetype(m.lcDrive),3,4)
set message to 'Searching drive '+m.lcDrive+m.MsgTail
loFiler.SearchPath = m.lcDrive+':\'
loFiler.find(0) && Perform search
if m.halt or lastkey()=27 && Escape was pressed
exit
endif
if loFiler.files.count>0 && At least one file was found, pick up the first
lcRetPath=loFiler.files.item[1].path
exit
endif
endif
endfor
endif
if m.lcPrevEscape='OFF'
set escape off
endif
on escape &lcPrevOnEsc
set message to ' '
wait clear
=messagebox("File "+iif(!empty(m.lcRetPath),m.lcRetPath+m.tcFileToSearch,"not")+" found in "+ ;
alltrim(str(seconds()-m.lnStartTime,10,3))+" sec.")
return m.lcRetPath && Path to the first found file
Oops, found another one, which, I guess, belongs to Mike. So, I'm not sure, who wrote the first one:
function FindFile
lparameters tcDir, lcFileName
if type('tcDir') 'C' or not directory(tcDir)
return
endif
local lnFiles, laFiles[1], lnI, lcDir
lcDir = iif(tcDir = "\" or ":" $ tcDir, ;
addbs(tcDir), fullpath(addbs(tcDir)))
wait window nowait lcDir
lnFiles = adir(laFiles, lcDir + '*', 'D')
for lnI = 1 to lnFiles
do case
case inlist(laFiles[lnI, 1], '.', '..')
loop
case 'D' $ laFiles[lnI, 5]
findfile(lcDir + laFiles[lnI, 1], lcFileName)
otherwise
lnTotalFiles = lnTotalFiles + 1
if laFiles[lnI, 1] = upper(lcFileName)
lnFoundFiles = lnFoundFiles + 1
endif
endcase
endfor
If it's not broken, fix it until it is.
My Blog