RDoes

Find File On Harddrive.

9 posts in this topic

Hi all,

Who can help me to build a function to finds a file in a given path.

It must search the current directory AND all subdirectory's.

The FileFindFirstFile() and FileFindNextFile() method searches only the current directory and NOT the subdirectory's

For example like:

Dim $Path="C:\Windows" ;The start directory for searching.

Dim $Result ;The full path where file is found, if not result = -1

Dim $File="Notepad.exe" ; The file to find.

$Result = FindMyFile($Path, $File)

msgbox(4096,"File Founded.", $Result

Thanks.

Share this post


Link to post
Share on other sites



Is there not a more direct way ?

Like calling a API or dll function within the script ?

Share this post


Link to post
Share on other sites

I think this is the straight-forwardest way :angry: .. but if you search the forums for "recursive" (or such-like) you will find at least one UDF that recurses "manually" with FileGetFirst etc. I think Larry wrote one B)

See .. even if you download a standalone tool like DiskData, it looks like each folder has to be recursed. So if DOS already has a wheel invented, and called it Dir, then I'm happy :evil:

One of the coolest things about Autoit is that it's like a virtual Lego-set. So don't be afraid of mixing and matching external utilities. Run and RunWait are our friends :whistle:

Share this post


Link to post
Share on other sites

Thanks Trids for your information.

I have write my own function for searching a file.

You can search for all files, files like *.txt or myfile.*

At the moment it is not possible to search like my*.* or like myfile.tx? (who has any ideas for it)

You can set a start directory = $StartDir

You set the mask to search = $FileToFind

You can set some options = $Options

1- Show Search status window

2- Return Path(s) only

4- Search Sub directory's

8- Cancel by first found

Use this example program to test.

#Include "FileSearch.au3"

Dim $FILES
Dim $DIR="C:\"             ; specify the directory to search
Dim $FILEMASK="*.txt"      ; specify the filemask
Dim $X

                     ;Options are :
                     ;1- Show Search status window.
                     ;2- Return Path(s) only
                     ;4- Search Sub directory's
                     ;8- Cancel by first found
 $FILES = FindFile($DIR, $FILEMASK, 13)
 
 If IsArray($FILES) then
   For $X = 0 To UBound($FILES)-1
     MsgBox(0,'test:' & $X,$FILES[$X])
   Next 
   Exit
 EndIf

Save the following code to a file named "FileSearch.au3"

#include-once
                                     ;Default value is listed first !
Opt("MustDeclareVars", 1)            ;0=no   , 1=require pre-declare
Opt("RunErrorsFatal", 0)          ;1=fatal  , 0=silent set @error
Opt("TrayIconDebug", 1)              ;0=no info, 1=debug line info



                     ;Options are :
                     ;1- Show Search status window.
                     ;2- Return Path(s) only
                     ;4- Search Sub directory's
                     ;8- Cancel by first found
Func FindFile($StartDir, $FileToFind, $Options)

Dim $DirNames[200000]
Local $Files
Local $TotalDirCount
Local $CurrDirIndex
Local $DirHandle
Local $Result
Local $FileIndex
Local $ResultFiles

;Show a status screen.
 If BitAND($Options,1) = 1 then
  SplashTextOn("Searching your drive ...", $StartDir, 600, 120, -1, -1, 22, "Arial", 10)
 EndIf
 
;Remove the end \ If specified
 If StringRight($StartDir,1) = "\" Then $StartDir = StringTrimRight($StartDir,1)
 
;Set Start dir in Array
 $TotalDirCount = $TotalDirCount + 1
 $DirNames[$TotalDirCount] = $StartDir

 While $TotalDirCount > $CurrDirIndex
   $CurrDirIndex = $CurrDirIndex + 1
   $DirHandle = FileFindFirstFile($DirNames[$CurrDirIndex] & "\*.*")
   If @Error then ExitLoop 
   
   If BitAND($Options,1) = 1 then
     ControlSetText("Searching your drive ...", _
                    "", _
                    "Static1", _
                    @CRLF & "Searching in Directory :" & _
                    @CRLF & $DirNames[$CurrDirIndex] & _
                    @CRLF & @CRLF & _
                    @CRLF & "Searching for" & @TAB & @TAB & $FileToFind & _
                    @CRLF & "Currently founded files" & @TAB & $FileIndex)
   EndIf
 
   While 1
     $Result = FileFindNextFile($DirHandle) 
     If @error Then ExitLoop
  
    ;Skip these references
     If $Result = "." Or $Result = ".." Or $Result = "RECYCLER" Or $Result = "System Volume Information" Then 
       ContinueLoop
     
    ;Add this Directory to Array   
     ElseIf StringInStr(FileGetAttrib($DirNames[$CurrDirIndex] & "\" & $Result),"D") > 0 And BitAND($Options,4) = 4 Then
       $TotalDirCount = $TotalDirCount + 1
     $DirNames[$TotalDirCount] = $DirNames[$CurrDirIndex] & "\" & $Result
       
     ;Check if it is an file matches the filter
    ElseIf FileFilter($Result, $FileToFind) > 0 Then
       $FileIndex = $FileIndex + 1
     
       If BitAND($Options,2) = 2 Then
         $Files = $Files & $DirNames[$CurrDirIndex] & "\" & @CR
       Else
         $Files = $Files & $DirNames[$CurrDirIndex] & "\" & $Result & @CR
       EndIf
  
       If BitAND($Options,8) = 8 Then ExitLoop
     EndIf
   Wend
   FileClose($DirHandle)  
 Wend
 
 If BitAND($Options,1) = 1 then
   SplashOff()
 EndIf
 
 If $FileIndex > 0 then
   $Files = StringTrimRight($Files,1)
   $ResultFiles = StringSplit($Files,@CR)   
   Return $ResultFiles
 Else
   Return 0
 EndIf
EndFunc



Func FileFilter($Value, $Filter)
 
 Select
  Case $Filter = "*" or $Filter = "*.*"       ;Finds everything.
    Return 1   

  Case StringLeft($Filter, 1) = "*"           ;Finds all Files with given Extension.
    If StringRight($Filter, 4) = StringRight($Value, 4) then
      Return 1
    Else
      Return 0
    EndIf   
  
  Case StringRight($Filter, 1) = "*"          ;Finds all file names with any extension.
    If StringTrimRight($Filter, 2) = StringTrimRight($Value, 4) then
      Return 1
    Else
      Return 0
    EndIf   
  
  Case Else
    If $Value = $Filter then
      Return 1
    Else
      Return 0 
    EndIf      
 EndSelect
EndFunc

Share this post


Link to post
Share on other sites

Hi,

cool stuff !!! There was a little Error, when the script should end,

if first match was found. I hopefully corrected it, use this ...

#include-once
                        ;Default value is listed first !
Opt("MustDeclareVars", 1);0=no   , 1=require pre-declare
Opt("RunErrorsFatal", 0);1=fatal , 0=silent set @error
Opt("TrayIconDebug", 1) ;0=no info, 1=debug line info

Func FindFile($StartDir, $FileToFind, $Options)

Dim $DirNames[200000]
Local $Files
Local $TotalDirCount
Local $CurrDirIndex
Local $DirHandle
Local $Result
Local $FileIndex
Local $ResultFiles

;Show a status screen

If BitAND($Options,1) = 1 then
    SplashTextOn("Datei wird gesucht ...", $StartDir, 600, 120, -1, -1, 22, "Arial", 10)
EndIf

;Remove the end \ If specified

If StringRight($StartDir,1) = "\" Then $StartDir = StringTrimRight($StartDir,1)

;Set Start dir in Array

$TotalDirCount = $TotalDirCount + 1
$DirNames[$TotalDirCount] = $StartDir

While $TotalDirCount > $CurrDirIndex
    $CurrDirIndex = $CurrDirIndex + 1
    $DirHandle = FileFindFirstFile($DirNames[$CurrDirIndex] & "\*.*")
    If @Error then ExitLoop 
  
    If BitAND($Options,1) = 1 then
        ControlSetText("Datei wird gesucht ...", _
                        "", _
                        "Static1", _
                        @CRLF & "Aktuelles Verzeichnis :" & _
                        @CRLF & $DirNames[$CurrDirIndex] & _
                        @CRLF & @CRLF & _
                        @CRLF & "Suche nach" & @TAB & @TAB & $FileToFind & _
                        @CRLF & "Gefundene Datei(en)" & @TAB & $FileIndex)
    EndIf

    While 1
        $Result = FileFindNextFile($DirHandle) 
        If @error Then ExitLoop
 
;Skip these references

        If $Result = "." Or $Result = ".." Or $Result = "RECYCLER" Or $Result = "System Volume Information" Then 
            ContinueLoop
    
;Add this Directory to Array   

            ElseIf StringInStr(FileGetAttrib($DirNames[$CurrDirIndex] & "\" & $Result),"D") > 0 And BitAND($Options,4) = 4 Then
                $TotalDirCount = $TotalDirCount + 1
                $DirNames[$TotalDirCount] = $DirNames[$CurrDirIndex] & "\" & $Result
      
;Check if it is an file matches the filter

            ElseIf FileFilter($Result, $FileToFind) > 0 Then
                $FileIndex = $FileIndex + 1
    
                If BitAND($Options,2) = 2 Then
                    $Files = $Files & $DirNames[$CurrDirIndex] & "\" & @CR
                Else
                    $Files = $Files & $DirNames[$CurrDirIndex] & "\" & $Result & @CR
                EndIf
            EndIf
    Wend
    FileClose($DirHandle)
    If $FileIndex = 1 AND BitAND($Options,8) = 8 Then ExitLoop
Wend

If BitAND($Options,1) = 1 then
    SplashOff()
EndIf

If $FileIndex > 0 then
    $Files = StringTrimRight($Files,1)
    $ResultFiles = StringSplit($Files,@CR)   
    Return $ResultFiles
Else
    Return 0
EndIf

EndFunc

Func FileFilter($Value, $Filter)

Select
    Case $Filter = "*" or $Filter = "*.*"      ;Finds everything.
    Return 1   

    Case StringLeft($Filter, 1) = "*"          ;Finds all Files with given Extension.
    If StringRight($Filter, 4) = StringRight($Value, 4) then
        Return 1
    Else
        Return 0
    EndIf   
 
    Case StringRight($Filter, 1) = "*"         ;Finds all file names with any extension.
    If StringTrimRight($Filter, 2) = StringTrimRight($Value, 4) then
        Return 1
    Else
        Return 0
    EndIf   
 
    Case Else
    If $Value = $Filter then
        Return 1
    Else
        Return 0 
    EndIf      
EndSelect

EndFunc

Share this post


Link to post
Share on other sites

#8 ·  Posted

On 3/26/2004 at 8:48 PM, RDoes said:

Thanks Trids for your information.

 

I have write my own function for searching a file.

You can search for all files, files like *.txt or myfile.*

At the moment it is not possible to search like my*.* or like myfile.tx? (who has any ideas for it)

 

You can set a start directory = $StartDir

You set the mask to search = $FileToFind

You can set some options = $Options

1- Show Search status window

2- Return Path(s) only

4- Search Sub directory's

8- Cancel by first found

 

 

Use this example program to test.

 

#Include "FileSearch.au3"

Dim $FILES
Dim $DIR="C:\"             ; specify the directory to search
Dim $FILEMASK="*.txt"      ; specify the filemask
Dim $X

                     ;Options are :
                     ;1- Show Search status window.
                     ;2- Return Path(s) only
                     ;4- Search Sub directory's
                     ;8- Cancel by first found
 $FILES = FindFile($DIR, $FILEMASK, 13)
 
 If IsArray($FILES) then
   For $X = 0 To UBound($FILES)-1
     MsgBox(0,'test:' & $X,$FILES[$X])
   Next 
   Exit
 EndIf

 

Save the following code to a file named "FileSearch.au3"

 

#include-once
                                     ;Default value is listed first !
Opt("MustDeclareVars", 1)            ;0=no   , 1=require pre-declare
Opt("RunErrorsFatal", 0)          ;1=fatal  , 0=silent set @error
Opt("TrayIconDebug", 1)              ;0=no info, 1=debug line info



                     ;Options are :
                     ;1- Show Search status window.
                     ;2- Return Path(s) only
                     ;4- Search Sub directory's
                     ;8- Cancel by first found
Func FindFile($StartDir, $FileToFind, $Options)

Dim $DirNames[200000]
Local $Files
Local $TotalDirCount
Local $CurrDirIndex
Local $DirHandle
Local $Result
Local $FileIndex
Local $ResultFiles

;Show a status screen.
 If BitAND($Options,1) = 1 then
  SplashTextOn("Searching your drive ...", $StartDir, 600, 120, -1, -1, 22, "Arial", 10)
 EndIf
 
;Remove the end \ If specified
 If StringRight($StartDir,1) = "\" Then $StartDir = StringTrimRight($StartDir,1)
 
;Set Start dir in Array
 $TotalDirCount = $TotalDirCount + 1
 $DirNames[$TotalDirCount] = $StartDir

 While $TotalDirCount > $CurrDirIndex
   $CurrDirIndex = $CurrDirIndex + 1
   $DirHandle = FileFindFirstFile($DirNames[$CurrDirIndex] & "\*.*")
   If @Error then ExitLoop 
   
   If BitAND($Options,1) = 1 then
     ControlSetText("Searching your drive ...", _
                    "", _
                    "Static1", _
                    @CRLF & "Searching in Directory :" & _
                    @CRLF & $DirNames[$CurrDirIndex] & _
                    @CRLF & @CRLF & _
                    @CRLF & "Searching for" & @TAB & @TAB & $FileToFind & _
                    @CRLF & "Currently founded files" & @TAB & $FileIndex)
   EndIf
 
   While 1
     $Result = FileFindNextFile($DirHandle) 
     If @error Then ExitLoop
  
    ;Skip these references
     If $Result = "." Or $Result = ".." Or $Result = "RECYCLER" Or $Result = "System Volume Information" Then 
       ContinueLoop
     
    ;Add this Directory to Array   
     ElseIf StringInStr(FileGetAttrib($DirNames[$CurrDirIndex] & "\" & $Result),"D") > 0 And BitAND($Options,4) = 4 Then
       $TotalDirCount = $TotalDirCount + 1
     $DirNames[$TotalDirCount] = $DirNames[$CurrDirIndex] & "\" & $Result
       
     ;Check if it is an file matches the filter
    ElseIf FileFilter($Result, $FileToFind) > 0 Then
       $FileIndex = $FileIndex + 1
     
       If BitAND($Options,2) = 2 Then
         $Files = $Files & $DirNames[$CurrDirIndex] & "\" & @CR
       Else
         $Files = $Files & $DirNames[$CurrDirIndex] & "\" & $Result & @CR
       EndIf
  
       If BitAND($Options,8) = 8 Then ExitLoop
     EndIf
   Wend
   FileClose($DirHandle)  
 Wend
 
 If BitAND($Options,1) = 1 then
   SplashOff()
 EndIf
 
 If $FileIndex > 0 then
   $Files = StringTrimRight($Files,1)
   $ResultFiles = StringSplit($Files,@CR)   
   Return $ResultFiles
 Else
   Return 0
 EndIf
EndFunc



Func FileFilter($Value, $Filter)
 
 Select
  Case $Filter = "*" or $Filter = "*.*"       ;Finds everything.
    Return 1   

  Case StringLeft($Filter, 1) = "*"           ;Finds all Files with given Extension.
    If StringRight($Filter, 4) = StringRight($Value, 4) then
      Return 1
    Else
      Return 0
    EndIf   
  
  Case StringRight($Filter, 1) = "*"          ;Finds all file names with any extension.
    If StringTrimRight($Filter, 2) = StringTrimRight($Value, 4) then
      Return 1
    Else
      Return 0
    EndIf   
  
  Case Else
    If $Value = $Filter then
      Return 1
    Else
      Return 0 
    EndIf      
 EndSelect
EndFunc

this post is work well for me, i just wonder how to compact 2 code into 1, i need it work in machine that not install autoit.

I know that topic is very old but hope someone can help

So many thank for you!

Share this post


Link to post
Share on other sites

#9 ·  Posted

bootlesnet,

You do realise that the post above yours dates from over 11 years ago? Please do not necro-post like this again - just start a new thread and link to the old one if necessary.

And to show why this is the way to go, AutoIt now has a standard function _FileListToArrayRec which carries out a recursive search within a given path and allows you find all files/folders that match a given template. So there was no need to look at code from this far back at all.

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now