Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
FindFirstFile
Message
 
 
To
29/06/2001 12:06:54
Alex Zhadanov
Computer Generated Solutions
New York City, New York, United States
General information
Forum:
Visual FoxPro
Category:
Windows API functions
Title:
Miscellaneous
Thread ID:
00521676
Message ID:
00525295
Views:
19
>>>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
* WARNING: If the user has a directory structure 32+ levels deep,
* this program will crash.
* This procedure will recursively search a specified directory and
* its subdirectories for a particular file and if found return the
* location from the root directory. If the file is not found, the
* message "FILE NOT FOUND!" will be displayed. Wildcard characters
* are not supported.
* Example of how to call this function is :
* TempVariable=FileFind("Customer.dbf","C:")

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
*
* This is the recursive part of the program. This function will
* search the specified directory and call itself again if needed to
* search a subdirectory.

parameter FILENAME, curdir
private FILENAME, curdir, temp_dir, i, j  && Private variables needed
* curdir is the current directory.        && for recursion to work.
* filename is the file being searched for.
dimension temp_dir(1,1)
temp_dir(1,1)=" "
=adir(temp_dir,curdir+"\"+FILENAME)
if ascan(temp_dir,upper(FILENAME)) != 0   && Search current directory
     filefound=curdir + "\"+ upper(FILENAME)
     return to FILEFIND                  && IF file found, end program
endif
=adir(temp_dir,curdir+"\*.","D")          && Get subdirectories
if temp_dir(1,1) != " " and filefound =" "&& Search subdirectories
     if temp_dir(1,1)="."                 && Look at first subdirectory
          if alen(temp_dir,1)=2         && Possibly no subdirectories
               return
          endif
          i=3
     else
          i=1
     endif
     for j = i to alen(temp_dir,1)  && Start searching subdirectories
          curdir=curdir+"\"+temp_dir(j,1)
          =filesrch(FILENAME,curdir)      && Recursive call
          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:
********************************************************************
*  Description.......: FindFileInNetwork
*  Calling Samples...: FindFileInNetwork("pdfmon.dll","c:\")
*  Parameter List....: tcFileToSearch, tcSearchPath, tlEntireNetwork
*  Created by........: Houston Brennan 06/13/2000
*  Modified by.......: Nadya Nosonovsky 06/16/2000 11:30:52 AM (with assistance of BP and JH)
********************************************************************
lparameters tcFileToSearch, tcSearchPath, tlEntireNetwork
** Check passed parameters
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=''
* note clock reading for generating final timing statistics
lnStartTime = seconds()                         && # seconds since midnight

* support user Escapes for interrupting the loop
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

* assemble fixed portion of status bar message outside of loop, for speed
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
** Want to search in the whole network
     for lni = 67 to 90
          lcDrive = chr(m.lni)
          if inlist(drivetype(m.lcDrive),3,4)
* Make sure the drive is ready (type 4 is either removeable or a network drive)
               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
* Restore settings
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

*Make sure we have a directory to loop through
if type('tcDir')  'C' or not directory(tcDir)
     return
endif

*Set up the variables we'll need
local lnFiles, laFiles[1], lnI, lcDir
lcDir          = iif(tcDir = "\" or ":" $ tcDir, ;
     addbs(tcDir), fullpath(addbs(tcDir)))
wait window nowait lcDir

*Loop through every file and driectory
lnFiles = adir(laFiles, lcDir + '*', 'D')
for lnI = 1 to lnFiles

     do case

          *Ignore these two
          case inlist(laFiles[lnI, 1], '.', '..')
               loop

          *Recurse for every directory
          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
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform