• Earn real money by being active: Hello Guest, earn real money by simply being active on the forum — post quality content, get reactions, and help the community. Once you reach the minimum credit amount, you’ll be able to withdraw your balance directly. Learn how it works.

AutoIT [Autoit] File/Folder recursive search

Status
Not open for further replies.

0b3y

☢AutoIt c0d3r☢
User
Joined
Nov 9, 2012
Messages
506
Reputation
0
Reaction score
570
Points
93
Credits
0
‎12 Years of Service‎
73%
This function searchs for a file/folder in the given path(can be all disk) and give the results on a file.

; #FUNCTION# ;================================================= ==============================


; Name...........: File/Folder Searcher Recurvise



; Description ...: Searches the given path(can be the full disk) for a file or a folder especificated.



; Syntax.........: _search_files ($Directory,$Search4,$What2Return,$file)



; Parameters ....: $Directory= Directory where to search for the file/s its a recursive search



; $Search4= Name of the folder or file to search for, you can use ? * as you would with CMD, also you can search for extension ex: "*.pdf". The search string must be between "



; $What2Return= If you want to return files and folders (0) only files (1) or only folders (2)



; $file= Absolut path to the file where to save the founded files.



; Return values .: Success - Returns 0



; Failure - Returns 1



; Author ........: 0b3y



;================================================= ===========================================


[HIDE-THANKS]

Code:
>
Func _search_files($d=@HomeDrive,$w="*",$c=0,$a=@TempDir&"\FilesReport.txt")
If $w="" Then
  Return 1
EndIf
$d=_FileListToArrayRec($d,$w,$c,1,0,2)
$p=FileOpen($a,2)
For $y=1 To $d[0]
  FileWrite($p,$d[$y]&@CRLF)
Next
If Not      [MENTION=8708]error[/MENTION] Then
  Return 0
else
  Return 1 
EndIf
EndFunc

Func _FileListToArrayRec($sFilePath, $sMask = "*", $iReturn = $FLTAR_FILESFOLDERS, $iRecur = $FLTAR_NORECUR, $iSort = $FLTAR_NOSORT, $iReturnPath = $FLTAR_RELPATH)
  $STR_STRIPLEADING = 1
  $STR_STRIPTRAILING = 2
If Not FileExists($sFilePath) Then Return SetError(1, 1, "")

; Check for Default keyword
If $sMask = Default Then $sMask = "*"
If $iReturn = Default Then $iReturn = $FLTAR_FILESFOLDERS
If $iRecur = Default Then $iRecur = $FLTAR_NORECUR
If $iSort = Default Then $iSort = $FLTAR_NOSORT
If $iReturnPath = Default Then $iReturnPath = $FLTAR_RELPATH

; Check for valid recur value
If $iRecur > 1 Or Not IsInt($iRecur) Then Return SetError(1, 6, "")

Local $bLongPath = False
; Check for valid path
If StringLeft($sFilePath, 4) == "\\?" Then
	$bLongPath = True
EndIf

Local $sFolderSlash = ""
; Check if folders should have trailing \ and ensure that initial path does have one
If StringRight($sFilePath, 1) = "" Then
	$sFolderSlash = ""
Else
	$sFilePath = $sFilePath & ""
EndIf

Local $asFolderSearchList[100] = [1]
; Add path to folder search list
$asFolderSearchList[1] = $sFilePath

Local $iHide_HS = 0, _
		$sHide_HS = ""
; Check for H or S omitted
If BitAND($iReturn, 4) Then
	$iHide_HS += 2
	$sHide_HS &= "H"
	$iReturn -= 4
EndIf
If BitAND($iReturn, 8) Then
	$iHide_HS += 4
	$sHide_HS &= "S"
	$iReturn -= 8
EndIf

Local $iHide_Link = 0
; Check for link/junction omitted
If BitAND($iReturn, 16) Then
	$iHide_Link = 0x400
	$iReturn -= 16
EndIf

Local $iMaxLevel = 0
; If required, determine \ count for max recursive level setting
If $iRecur < 0 Then
	StringReplace($sFilePath, "", "", 0, $STR_NOCASESENSEBASIC)
	$iMaxLevel = @extended - $iRecur
EndIf

Local $sExclude_List = "", $sExclude_List_Folder = "", $sInclude_List = "*"
; Check mask parameter
Local $aMaskSplit = StringSplit($sMask, "|")
; Check for multiple sections and set values
Switch $aMaskSplit[0]
	Case 3
		$sExclude_List_Folder = $aMaskSplit[3]
		ContinueCase
	Case 2
		$sExclude_List = $aMaskSplit[2]
		ContinueCase
	Case 1
		$sInclude_List = $aMaskSplit[1]
EndSwitch

Local $sInclude_File_Mask = ".+"
; Create Include mask for files
If $sInclude_List <> "*" Then
	If Not __FLTAR_ListToMask($sInclude_File_Mask, $sInclude_List) Then Return SetError(1, 2, "")
EndIf

Local $sInclude_Folder_Mask = ".+"
; Set Include mask for folders
Switch $iReturn
	Case 0
		; Folders affected by mask if not recursive
		Switch $iRecur
			Case 0
				; Folders match mask for compatibility
				$sInclude_Folder_Mask = $sInclude_File_Mask
		EndSwitch
	Case 2
		; Folders affected by mask
		$sInclude_Folder_Mask = $sInclude_File_Mask
EndSwitch

Local $sExclude_File_Mask = ":"
; Create Exclude List mask for files
If $sExclude_List <> "" Then
	If Not __FLTAR_ListToMask($sExclude_File_Mask, $sExclude_List) Then Return SetError(1, 3, "")
EndIf

Local $sExclude_Folder_Mask = ":"
; Create Exclude mask for folders
If $iRecur Then
	If $sExclude_List_Folder Then
		If Not __FLTAR_ListToMask($sExclude_Folder_Mask, $sExclude_List_Folder) Then Return SetError(1, 4, "")
	EndIf
	; If folders only
	If $iReturn = 2 Then
		; Folders affected by normal mask
		$sExclude_Folder_Mask = $sExclude_File_Mask
	EndIf
Else
	; Folders affected by normal mask
	$sExclude_Folder_Mask = $sExclude_File_Mask
EndIf

; Verify other parameters
If Not ($iReturn = 0 Or $iReturn = 1 Or $iReturn = 2) Then Return SetError(1, 5, "")
If Not ($iSort = 0 Or $iSort = 1 Or $iSort = 2) Then Return SetError(1, 7, "")
If Not ($iReturnPath = 0 Or $iReturnPath = 1 Or $iReturnPath = 2) Then Return SetError(1, 8, "")

; Prepare for DllCall if required
If $iHide_Link Then
	Local $tFile_Data = DllStructCreate("struct;align 4;dword FileAttributes;uint64 CreationTime;uint64 LastAccessTime;uint64 LastWriteTime;" & _
			"dword FileSizeHigh;dword FileSizeLow;dword Reserved0;dword Reserved1;wchar FileName[260];wchar AlternateFileName[14];endstruct")
	Local $hDLL = DllOpen('kernel32.dll'), $aDLL_Ret
EndIf

Local $asReturnList[100] = [0]
Local $asFileMatchList = $asReturnList, $asRootFileMatchList = $asReturnList, $asFolderMatchList = $asReturnList
Local $bFolder = False, _
		$hSearch = 0, _
		$sCurrentPath = "", $sName = "", $sRetPath = ""
Local $iAttribs = 0, _
		$sAttribs = ''
Local $asFolderFileSectionList[100][2] = [[0, 0]]
; Search within listed folders
While $asFolderSearchList[0] > 0

	; Set path to search
	$sCurrentPath = $asFolderSearchList[$asFolderSearchList[0]]
	; Reduce folder search list count
	$asFolderSearchList[0] -= 1
	; Determine return path to add to file/folder name
	Switch $iReturnPath
		; Case 0 ; Name only
		; Leave as ""
		Case 1 ;Relative to initial path
			$sRetPath = StringReplace($sCurrentPath, $sFilePath, "")
		Case 2 ; Full path
			If $bLongPath Then
				$sRetPath = StringTrimLeft($sCurrentPath, 4)
			Else
				$sRetPath = $sCurrentPath
			EndIf
	EndSwitch

	; Get search handle - use code matched to required listing
	If $iHide_Link Then
		; Use DLL code
		$aDLL_Ret = DllCall($hDLL, 'handle', 'FindFirstFileW', 'wstr', $sCurrentPath & "*", 'struct*', $tFile_Data)
		If      [MENTION=8708]error[/MENTION] Or Not $aDLL_Ret[0] Then
			ContinueLoop
		EndIf
		$hSearch = $aDLL_Ret[0]
	Else
		; Use native code
		$hSearch = FileFindFirstFile($sCurrentPath & "*")
		; If folder empty move to next in list
		If $hSearch = -1 Then
			ContinueLoop
		EndIf
	EndIf

	; If sorting files and folders with paths then store folder name and position of associated files in list
	If $iReturn = 0 And $iSort And $iReturnPath Then
		__FLTAR_AddToList($asFolderFileSectionList, $sRetPath, $asFileMatchList[0] + 1)
	EndIf
	$sAttribs = ''

	; Search folder - use code matched to required listing
	While 1
		; Use DLL code
		If $iHide_Link Then
			; Use DLL code
			$aDLL_Ret = DllCall($hDLL, 'int', 'FindNextFileW', 'handle', $hSearch, 'struct*', $tFile_Data)
			; Check for end of folder
			If      [MENTION=8708]error[/MENTION] Or Not $aDLL_Ret[0] Then
				ExitLoop
			EndIf
			; Extract data
			$sName = DllStructGetData($tFile_Data, "FileName")
			; Check for .. return - only returned by the DllCall
			If $sName = ".." Then
				ContinueLoop
			EndIf
			$iAttribs = DllStructGetData($tFile_Data, "FileAttributes")
			; Check for hidden/system attributes and skip if found
			If $iHide_HS And BitAND($iAttribs, $iHide_HS) Then
				ContinueLoop
			EndIf
			; Check for link attribute and skip if found
			If BitAND($iAttribs, $iHide_Link) Then
				ContinueLoop
			EndIf
			; Set subfolder flag
			$bFolder = False
			If BitAND($iAttribs, 16) Then
				$bFolder = True
			EndIf
		Else
			; Reset folder flag
			$bFolder = False
			; Use native code
			$sName = FileFindNextFile($hSearch, 1)
			; Check for end of folder
			If      [MENTION=8708]error[/MENTION] Then
				ExitLoop
			EndIf
			$sAttribs = @extended
			; Check for folder
			If StringInStr($sAttribs, "D") Then
				$bFolder = True
			EndIf
			; Check for Hidden/System
			If StringRegExp($sAttribs, "[" & $sHide_HS & "]") Then
				ContinueLoop
			EndIf
		EndIf

		; If folder then check whether to add to search list
		If $bFolder Then
			Select
				Case $iRecur < 0 ; Check recur depth
					StringReplace($sCurrentPath, "", "", 0, $STR_NOCASESENSEBASIC)
					If @extended < $iMaxLevel Then
						ContinueCase ; Check if matched to masks
					EndIf
				Case $iRecur = 1 ; Full recur
					If Not StringRegExp($sName, $sExclude_Folder_Mask) Then ; Add folder unless excluded
						__FLTAR_AddToList($asFolderSearchList, $sCurrentPath & $sName & "")
					EndIf
					; Case $iRecur = 0 ; Never add
					; Do nothing
			EndSelect
		EndIf

		If $iSort Then ; Save in relevant folders for later sorting
			If $bFolder Then
				If StringRegExp($sName, $sInclude_Folder_Mask) And Not StringRegExp($sName, $sExclude_Folder_Mask) Then
					__FLTAR_AddToList($asFolderMatchList, $sRetPath & $sName & $sFolderSlash)
				EndIf
			Else
				If StringRegExp($sName, $sInclude_File_Mask) And Not StringRegExp($sName, $sExclude_File_Mask) Then
					; Select required list for files
					If $sCurrentPath = $sFilePath Then
						__FLTAR_AddToList($asRootFileMatchList, $sRetPath & $sName)
					Else
						__FLTAR_AddToList($asFileMatchList, $sRetPath & $sName)
					EndIf
				EndIf
			EndIf
		Else ; Save directly in return list
			If $bFolder Then
				If $iReturn <> 1 And StringRegExp($sName, $sInclude_Folder_Mask) And Not StringRegExp($sName, $sExclude_Folder_Mask) Then
					__FLTAR_AddToList($asReturnList, $sRetPath & $sName & $sFolderSlash)
				EndIf
			Else
				If $iReturn <> 2 And StringRegExp($sName, $sInclude_File_Mask) And Not StringRegExp($sName, $sExclude_File_Mask) Then
					__FLTAR_AddToList($asReturnList, $sRetPath & $sName)
				EndIf
			EndIf
		EndIf

	WEnd

	; Close current search
	If $iHide_Link Then
		DllCall($hDLL, 'int', 'FindClose', 'ptr', $hSearch)
	Else
		FileClose($hSearch)
	EndIf

WEnd

; Close the DLL if needed
If $iHide_Link Then
	DllClose($hDLL)
EndIf

; Sort results if required
If $iSort Then
	Switch $iReturn
		Case 2 ; Folders only
			; Check if any folders found
			If $asFolderMatchList[0] = 0 Then Return SetError(1, 9, "")
			; Correctly size folder match list
			ReDim $asFolderMatchList[$asFolderMatchList[0] + 1]
			; Copy size folder match array
			$asReturnList = $asFolderMatchList
			; Simple sort list
			__ArrayDualPivotSort($asReturnList, 1, $asReturnList[0])
		Case 1 ; Files only
			; Check if any files found
			If $asRootFileMatchList[0] = 0 And $asFileMatchList[0] = 0 Then Return SetError(1, 9, "")
			If $iReturnPath = 0 Then ; names only so simple sort suffices
				; Combine file match lists
				__FLTAR_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList)
				; Simple sort combined file list
				__ArrayDualPivotSort($asReturnList, 1, $asReturnList[0])
			Else
				; Combine sorted file match lists
				__FLTAR_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList, 1)
			EndIf
		Case 0 ; Both files and folders
			; Check if any root files or folders found
			If $asRootFileMatchList[0] = 0 And $asFolderMatchList[0] = 0 Then Return SetError(1, 9, "")
			If $iReturnPath = 0 Then ; names only so simple sort suffices
				; Combine file match lists
				__FLTAR_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList)
				; Set correct count for folder add
				$asReturnList[0] += $asFolderMatchList[0]
				; Resize and add file match array
				ReDim $asFolderMatchList[$asFolderMatchList[0] + 1]
				_ArrayConcatenate($asReturnList, $asFolderMatchList, 1)
				; Simple sort final list
				__ArrayDualPivotSort($asReturnList, 1, $asReturnList[0])
			Else
				; Size return list
				Local $asReturnList[$asFileMatchList[0] + $asRootFileMatchList[0] + $asFolderMatchList[0] + 1]
				$asReturnList[0] = $asFileMatchList[0] + $asRootFileMatchList[0] + $asFolderMatchList[0]
				; Sort root file list
				__ArrayDualPivotSort($asRootFileMatchList, 1, $asRootFileMatchList[0])
				; Add the sorted root files at the top
				For $i = 1 To $asRootFileMatchList[0]
					$asReturnList[$i] = $asRootFileMatchList[$i]
				Next
				; Set next insertion index
				Local $iNextInsertionIndex = $asRootFileMatchList[0] + 1
				; Sort folder list
				__ArrayDualPivotSort($asFolderMatchList, 1, $asFolderMatchList[0])
				Local $sFolderToFind = ""
				; Work through folder list
				For $i = 1 To $asFolderMatchList[0]
					; Add folder to return list
					$asReturnList[$iNextInsertionIndex] = $asFolderMatchList[$i]
					$iNextInsertionIndex += 1
					; Format folder name for search
					If $sFolderSlash Then
						$sFolderToFind = $asFolderMatchList[$i]
					Else
						$sFolderToFind = $asFolderMatchList[$i] & ""
					EndIf
					Local $iFileSectionEndIndex = 0, $iFileSectionStartIndex = 0
					; Find folder in FolderFileSectionList
					For $j = 1 To $asFolderFileSectionList[0][0]
						; If found then deal with files
						If $sFolderToFind = $asFolderFileSectionList[$j][0] Then
							; Set file list indexes
							$iFileSectionStartIndex = $asFolderFileSectionList[$j][1]
							If $j = $asFolderFileSectionList[0][0] Then
								$iFileSectionEndIndex = $asFileMatchList[0]
							Else
								$iFileSectionEndIndex = $asFolderFileSectionList[$j + 1][1] - 1
							EndIf
							; Sort files if required
							If $iSort = 1 Then
								__ArrayDualPivotSort($asFileMatchList, $iFileSectionStartIndex, $iFileSectionEndIndex)
							EndIf
							; Add files to return list
							For $k = $iFileSectionStartIndex To $iFileSectionEndIndex
								$asReturnList[$iNextInsertionIndex] = $asFileMatchList[$k]
								$iNextInsertionIndex += 1
							Next
							ExitLoop
						EndIf
					Next
				Next
			EndIf
	EndSwitch
Else ; No sort
	; Check if any file/folders have been added
	If $asReturnList[0] = 0 Then Return SetError(1, 9, "")
	; Remove any unused return list elements from last ReDim
	ReDim $asReturnList[$asReturnList[0] + 1]

EndIf

Return $asReturnList
EndFunc   ;==>_FileListToArrayRec

Func __FLTAR_ListToMask(ByRef $sMask, $sList)
; Check for invalid characters within list
If StringRegExp($sList, "\\|/|:|\<|\>|\|") Then Return 0
; Strip WS and insert | for ;
$sList = StringReplace(StringStripWS(StringRegExpReplace($sList, "\s*;\s*", ";"), $STR_STRIPLEADING + $STR_STRIPTRAILING), ";", "|")
; Convert to SRE pattern
$sList = StringReplace(StringReplace(StringRegExpReplace($sList, "[][$^.{}()+\-]", "\\$0"), "?", "."), "*", ".*?")
; Add prefix and suffix
$sMask = "(?i)^(" & $sList & ")\z"
Return 1
EndFunc   ;==>__FLTAR_ListToMask

Func __FLTAR_AddToList(ByRef $aList, $vValue_0, $vValue_1 = -1)
If $vValue_1 = -1 Then ; [?] array
	; Increase list count
	$aList[0] += 1
	; Double list size if too small (fewer ReDim needed)
	If UBound($aList) <= $aList[0] Then ReDim $aList[uBound($aList) * 2]
	; Add value
	$aList[$aList[0]] = $vValue_0
Else ; [?][2] array
	$aList[0][0] += 1
	If UBound($aList) <= $aList[0][0] Then ReDim $aList[uBound($aList) * 2][2]
	$aList[$aList[0][0]][0] = $vValue_0
	$aList[$aList[0][0]][1] = $vValue_1
EndIf
EndFunc   ;==>__FLTAR_AddToList
[/HIDE-THANKS]

 
Last edited by a moderator:
Status
Not open for further replies.
Back
Top