godsstigma Posted January 20, 2009 Share Posted January 20, 2009 I have searched the help file and the forums up and down but I just can not seem to find a solid answer. I am looking for a function that will perform a recursive search for a file and retrieve the full file path including the file name. I need to search for multiple files of the same extension so it would be best if it outputted the full file path and file name to an array. Any help would be much appreciated. Thanks. Link to comment Share on other sites More sharing options...
tannerli Posted January 20, 2009 Share Posted January 20, 2009 Recursive SearchActually, i wrote this code just now... you may have to edit it a little but in general it does what you want Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted January 20, 2009 Moderators Share Posted January 20, 2009 (edited) Hi, This is a recursive search script that I use. I found it on the forums a while ago, but I have no idea of the original author - so credit to who ever it was!. Might need a bit of tweaking to fit your requirements, but I have found it very reliable.; Search ("Base folder", "filename");replace as required Func Search($current,$toFind) If StringRight($current,1) <> "\" then $current &= "\" Local $search_handle = FileFindFirstFile($current & "*.*") While 1 $file_found = FileFindNextFile($search_handle) If @error Or StringLen($file_found) < 1 Then ExitLoop If StringInStr(FileGetAttrib($current & $file_found), "D") And ($file_found <> "." Or $file_found <> "..") Then ; Search this subfolder Search($current & $file_found, $toFind) Else ; Found file EndIf WEnd FileClose($search_handle) EndFunc M23 Edited January 20, 2009 by Melba23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
Malkey Posted January 20, 2009 Share Posted January 20, 2009 I have searched the help file and the forums up and down but I just can not seem to find a solid answer. I am looking for a function that will perform a recursive search for a file and retrieve the full file path including the file name. I need to search for multiple files of the same extension so it would be best if it outputted the full file path and file name to an array. Any help would be much appreciated. Thanks.Another example. It appears to be working correctly. #include <File.au3> #include <Array.au3> Global $sRet Local $sPath = @WindowsDir Local $sFindFile = "calc.exe" $aRetArray = _FindPathName($sPath, $sFindFile) _ArrayDisplay($aRetArray) ; Searches all subfolders of $sPath for $sFindFile (* and ? wildcards accepted) ; Returns an array containing full path and name of all matches. ; Number of matches is in zero index of array Func _FindPathName($sPath, $sFindFile) Local $sSubFolderPath, $iIndex, $aFolders $search = FileFindFirstFile($sPath & "\" & $sFindFile) $aFolders = _FileListToArray($sPath, "*", 2) While 1 $file = FileFindNextFile($search) If @error Then ExitLoop Else $sRet &= $sPath & "\" & $file & "|" EndIf WEnd FileClose($search) For $iIndex = 1 To $aFolders[0] $sSubFolderPath = $sPath & "\" & $aFolders[$iIndex] $aFoldersSubs = _FileListToArray($sSubFolderPath, "*", 2) If IsArray($aFoldersSubs) Then _FindPathName($sSubFolderPath, $sFindFile) Next Return StringSplit(StringTrimRight($sRet,1), "|") EndFunc ;==>_FindPathName Link to comment Share on other sites More sharing options...
godsstigma Posted January 21, 2009 Author Share Posted January 21, 2009 Wow... Either you guys really like to post about recursive searches or this is the most helpful forum I have ever been to! Thanks so much... I don't know which one to use first! Link to comment Share on other sites More sharing options...
godsstigma Posted January 21, 2009 Author Share Posted January 21, 2009 Another example. It appears to be working correctly. #include <File.au3> #include <Array.au3> Global $sRet Local $sPath = @WindowsDir Local $sFindFile = "calc.exe" $aRetArray = _FindPathName($sPath, $sFindFile) _ArrayDisplay($aRetArray) ; Searches all subfolders of $sPath for $sFindFile (* and ? wildcards accepted) ; Returns an array containing full path and name of all matches. ; Number of matches is in zero index of array Func _FindPathName($sPath, $sFindFile) Local $sSubFolderPath, $iIndex, $aFolders $search = FileFindFirstFile($sPath & "\" & $sFindFile) $aFolders = _FileListToArray($sPath, "*", 2) While 1 $file = FileFindNextFile($search) If @error Then ExitLoop Else $sRet &= $sPath & "\" & $file & "|" EndIf WEnd FileClose($search) For $iIndex = 1 To $aFolders[0] $sSubFolderPath = $sPath & "\" & $aFolders[$iIndex] $aFoldersSubs = _FileListToArray($sSubFolderPath, "*", 2) If IsArray($aFoldersSubs) Then _FindPathName($sSubFolderPath, $sFindFile) Next Return StringSplit(StringTrimRight($sRet,1), "|") EndFunc ;==>_FindPathName Malkey, I decided to go with your code being that it seemed to be the most strait forward to me... not that the others are bad though. Anyway, I am very new to AutoIt and my only scripting experience in with Auto Hot Key (I actually thought AutoIt would be similar, but not so much)... so would you mind explaining exactly what you did here? (especially the string functions which I have a hard time understanding) I would appreciate it very much! Link to comment Share on other sites More sharing options...
Malkey Posted January 21, 2009 Share Posted January 21, 2009 Malkey,I decided to go with your code being that it seemed to be the most strait forward to me... not that the others are bad though.Anyway, I am very new to AutoIt and my only scripting experience in with Auto Hot Key (I actually thought AutoIt would be similar, but not so much)...so would you mind explaining exactly what you did here? (especially the string functions which I have a hard time understanding)I would appreciate it very much!godsstigma,FileFindFirstFile(),FileFindNextFile(), and FileClose() work together.And,_FileListToArray(), StringSplit(), andStringTrimRight are all in the help file.When a matching file is found, the line$sRet &= $sPath & "\" & $file & "|"adds to the $sRet string, $sPath & "\" & $file & "|". This line using '&=' is a short-cut way of writing,$sRet = $sRet & $sPath & "\" & $file & "|".The "|" is there as a separator of the different matches found. It could be anything. As long as it is will not appear as a character in the found path/file name.Because, on the Return line in the script, the string is split into an array using this character "|" as a delimiter. StringSplit(StringTrimRight($sRet,1), "|")But before the string is split, the last "|" of the $sRet string needs to be deleted. If not deleted, the StringSplit() will also split on the last "|" at the end of the string, $sRet, returning an array with a false blank array element at the end.The StringTrimRight() function used, removes one character from the right of the string, $sRet, which is, and will be "|".Hope this helps.Malkey Link to comment Share on other sites More sharing options...
godsstigma Posted January 21, 2009 Author Share Posted January 21, 2009 Excellent! thanks so much! Link to comment Share on other sites More sharing options...
Saruman Posted February 11, 2009 Share Posted February 11, 2009 Hi, I wrote this function for search files from a top folder specified as input value. My main objective was to have a simple function that I can include in other codes, when I need to search or locate files in a tree. I had located other codes, but those are ones that I need to embed my target operation INSIDE the search code. Let me explain this: Fucntion SearchFile (File_to find) (Begin search engine) ; ----- Target Operation: If file searched found, then do whatever you want (End of search Engine) EndFunction In other words, I need to modify the search function for every application that need search for a file. My point is that I don´t want to touch a function that I had already tested and is working properly. I need a simple call to a function to search a file, do whatever I want with that file, and close the search whenever I need. For example: Function My_Taget_Function (My_Input Values) Some code (...) ; Then I need to search file(s) !!! $NotFound=True While $NotFound $File=ScanFolder(C:\Documents and Settings) If This is my file then Do whatever I want with the file ; And then stop search when done: ScanFolder (-ABORT-) EndIf Wend (...) EndFunction This is my code. I hope result useful for anyone. Greetings! expandcollapse popup;---------------------------------------------------------------------------------------------------- ; Scan Folder Function ; ; This Function scans files in the folder specified and sub folders tree (if any) ; The first time it´s invoked CREATES a Search and returns the FULL PATH of the File found ; Subsecuents calls, continues the search until no more files are found and closes de search ; When end of search is reached, RETURNS -1 instead of the file name. ; ; If the caller wants to cancel/stop/abort the search, calls the function with the Keyword "-ABORT-" ; as Source Folder. ; ; Input: ; Start Folder to Scan or "-ABORT-" ; Returns: ; Full path to file found or -1 ;---------------------------------------------------------------------------------------------------- #include-once #Include <Array.au3> ; Field Definition Enum $_FLD_SourceFolder, $_FLD_SearchHandle, $_FLD_File, $_FLD_FullFilePath, $_FLD_FileAttributes, $_FLD_SearchStat, $_FLD_RecursionLevel, $_Dim Const $Stack_Deep = $_Dim * 256 ; Work Arrays for the Function DIM $SD [$_Dim] DIM $Stack [$Stack_Deep] Dim $Stack_Pointer = $Stack_Deep - 1 ; Default Values $SD [$_FLD_SourceFolder] = "NONE" $SD [$_FLD_SearchHandle] = 0 $SD [$_FLD_File] = "NONE" $SD [$_FLD_FullFilePath] = "NONE" $SD [$_FLD_FileAttributes] = "NONE" $SD [$_FLD_SearchStat] = "INIT" $SD [$_FLD_RecursionLevel] = 0 Func PushDTA () Local $i For $i = 0 to ($_Dim - 1) $Stack [$Stack_Pointer] = $SD [$i] $Stack_Pointer -= 1 Next $SD [$_FLD_RecursionLevel] += 1 EndFunc Func PopDTA () Local $i For $i = ($_Dim - 1) to 0 Step -1 $Stack_Pointer += 1 $SD[$i] = $Stack[$Stack_Pointer] Next EndFunc Func ScanFolder($SourceFolder) Local $RetVal = "" If $SourceFolder == "-ABORT-" Then Switch $SD [$_FLD_SearchStat] Case "INIT" $RetVal = -1 ; Nothing Done - Return Case "FIND_FIRST" $SD [$_FLD_SearchStat] = "ABORT" Case "FIND_NEXT" $SD [$_FLD_SearchStat] = "ABORT" Case Else MsgBox(48,"ERROR","Unknown Internal Search State. ABORTED!") $RetVal = -1 EndSwitch EndIf While $RetVal = "" Switch $SD [$_FLD_SearchStat] Case "INIT" ; Init Search Array If StringRight($SourceFolder,1) == "\" Then $SourceFolder = StringLeft($SourceFolder,StringLen($SourceFolder)-1) EndIf $SD [$_FLD_SourceFolder] = $SourceFolder $SD [$_FLD_SearchHandle] = 0 $SD [$_FLD_File] = "NONE" $SD [$_FLD_FullFilePath] = "NONE" $SD [$_FLD_FileAttributes] = "NONE" $SD [$_FLD_SearchStat] = "FIND_FIRST"; Next Phase $SD [$_FLD_RecursionLevel] = 0 Case "FIND_FIRST" $SD [$_FLD_SearchHandle] = FileFindFirstFile($SD [$_FLD_SourceFolder] & "\*.*") If $SD [$_FLD_SearchHandle] = -1 Then If $SD [$_FLD_RecursionLevel] < 1 Then ; Top Level ? $SD [$_FLD_SearchStat] = "INIT" ; Next Phase Start. Work Done. $RetVal = -1 ; End Execution and Retval NoMoreFiles Else PopDTA() ; Not in Top Level, Continue. EndIf Else $SD [$_FLD_SearchStat] = "FIND_NEXT" ; OK, Find Next File. EndIf Case "FIND_NEXT" $SD [$_FLD_File] = FileFindNextFile($SD [$_FLD_SearchHandle]) IF @error Then If $SD [$_FLD_RecursionLevel] < 1 Then ; Top Level ? $SD [$_FLD_SearchStat] = "INIT" ; Next Phase Start. Work Done. $RetVal = -1 ; End Execution and Retval NoMoreFiles FileClose($SD [$_FLD_SearchHandle]) Else FileClose($SD [$_FLD_SearchHandle]) ; No More Files in current Level. Close current Search PopDTA() ; Continue in upper level. EndIf Else $SD [$_FLD_FullFilePath] = $SD [$_FLD_SourceFolder] & "\" & $SD [$_FLD_File] ; $FullFilePath = $SourceFolder & "\" & $ File $SD [$_FLD_FileAttributes] = FileGetAttrib($SD [$_FLD_FullFilePath]) ; $FileAttributes = FileGetAttrib($FullFilePath) If StringInStr($SD [$_FLD_FileAttributes],"D") Then ; If StringInStr($FileAttributes,"D") Then PushDTA() ; If Directory, Save Data and start recursion $SD [$_FLD_SourceFolder] = $SD [$_FLD_FullFilePath] $SD [$_FLD_SearchStat] = "FIND_FIRST" ; Next Phase: Find First starting from here Else ; Normal File To Report $RetVal = $SD [$_FLD_FullFilePath] ; Exit Procedure Returning File Found EndIf EndIf Case "ABORT" While $SD [$_FLD_RecursionLevel] > 0 FileClose($SD [$_FLD_SearchHandle]) PopDTA() WEnd If $SD [$_FLD_SearchHandle] > -1 Then FileClose($SD [$_FLD_SearchHandle]) EndIf $SD [$_FLD_SearchStat] = "INIT" ; Next Phase Start. Work Done. $RetVal = -1 Case Else MsgBox(48,"ERROR","Unknown Internal Search State. ABORTED!") $RetVal = -1 EndSwitch WEnd Return $RetVal EndFunc ; -------------------------------------------------------- ; ; MAIN - TESTING ; ; -------------------------------------------------------- $File="" $Count=0 While $File > -1 $File = ScanFolder("C:\") ToolTip($File,0,200) FileWriteLine(@ScriptDir & "\ScanFolder.txt" ,$File) $Count += 1 If $Count >= 2000 Then $File = ScanFolder("-ABORT-") EndIf WEnd MsgBox(0,"Scan Completed","Files Found: " & $Count)Funct_ScanFolder.au3 Link to comment Share on other sites More sharing options...
ricky Posted April 16, 2009 Share Posted April 16, 2009 (edited) Hello Saruman, thanks for this source code, but I have a question. How can I modify this code to search one file (example : system.exe) in a patch c:\? I want already have the properties of the file(s), size, version, date,... Could you help me? Thanks in advance, Regards Edited April 16, 2009 by ricky03 Link to comment Share on other sites More sharing options...
Saruman Posted May 19, 2009 Share Posted May 19, 2009 (edited) Hello Saruman, thanks for this source code, but I have a question. How can I modify this code to search one file (example : system.exe) in a patch c:\? I want already have the properties of the file(s), size, version, date,... Could you help me? Thanks in advance, Regards Hello ricky03. First of all, sorry for the delayed reply, but I´m was off-line for some time. I think that you do not need to modify the search code. In your main code you can filter the result what you want. For example: $File="" $Version="" $Size="" $FileDate="" While $File > -1 $File = ScanFolder("C:\") If StringInstr($File, "system.exe") Then $Version=FileGetVersion($File, "FileVersion") $Size=FileGetSize ($File) $FileDate=FileGetTime ( $File,1,1) ; ETC..... FileWriteLine(@ScriptDir & "\ScanFolder.csv" ,$File & "," & $Version & "," & $Size & "," & $FileDate) EndIf ToolTip($File,0,200) WEnd I hope this can help you. Regards! Edited May 19, 2009 by Saruman Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now