z0iid Posted January 9, 2012 Posted January 9, 2012 I would imagine you do not need to test. I did a manual copy of another users directory that was getting the same problem to another share. Original share: linxux/netware/cifs - produced the self referencing loop New share: windows/active directory share - produced the correct number of files/folders - no loops So, unless you want to support file shares on essentially deprecated technology - your function works as designed. Leaving in the one liner to specifically exclude folders named . and .. from being actioned is probably good error control even though a standard windows share would likely never run up against it.
Moderators Melba23 Posted January 9, 2012 Author Moderators Posted January 9, 2012 z0iid, Thanks for testing that - I will keep it in mind for the next update. M23 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
GhostProtocol Posted January 10, 2012 Posted January 10, 2012 Hey guys thanks a ton for looking into this, I will add the modified UDF to my main script and test it out.
address Posted February 17, 2012 Posted February 17, 2012 #include <File.au3> #include <RecFileListToArray.au3> Global $Dir[20] $Dir[0] = "d:Misc" $Dir[1] = "" $Dir[2] = "" For $i = 0 To UBound($Dir) - 1 If $Dir[$i] = "" Then ContinueLoop _Search($Dir[$i], 0) _Search($Dir[$i], 1) Next Func _Search($Dir, $iRecursion) $aFiles = _RecFileListToArray($Dir, "*.jpg; *.png; *.gif", 1, $iRecursion, 0, 2, "", "") If Not IsArray($aFiles) Then MsgBox(16, "Error", "Invalid input path"& @CRLF & $Dir) Return Else If $iRecursion = 0 Then $hFile = FileOpen(@ScriptDir & "1.txt",1) Else $hFile = FileOpen(@ScriptDir & "2.txt",1) EndIf _FileWriteFromArray($hFile, $aFiles, 1) FileClose($hFile) EndIf EndFunc extension mask doesn' work. help please
Moderators Melba23 Posted February 17, 2012 Author Moderators Posted February 17, 2012 address, Your script as posted run on one of my folders returns the correct number of files of all requested types in both simple and recursive modes. What exactly does not work for you? Do you get any files returned? Only some? M23 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
Moderators Melba23 Posted February 17, 2012 Author Moderators Posted February 17, 2012 address,First time I have ever fixed anything by merely saying that "it works for me"! Glad you got it working now. M23 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
address Posted February 18, 2012 Posted February 18, 2012 #include <RecFileListToArray.au3> #include <File.au3> $aFiles = _RecFileListToArray("d:Misc", "*.jpg; *.png; *.gif", 1, 0, 0, 2, "", ""); second number with or without subfolders $hFile = FileOpen(@ScriptDir & "1.txt",1) _FileWriteFromArray($hFile, $aFiles, 1) FileClose($hFile) Can you show me please an example, how do I exclude two folders from my big folder? If I exclude them, files from these subfolders won't show up in search?
Moderators Melba23 Posted February 18, 2012 Author Moderators Posted February 18, 2012 address,If you want to exclude folders then you need to use the "files and folders" return option - that is the only one which honours the $sExclude_List_Folder list. So if you have a folder tree like this:Test-| |-First Folder | |-Second Folder | |-Third Folder | |-Fourth Folderthis code will search in all folders other than "Second Folder" and "Third Folder":$aList = _RecFileListToArray("N:Test", "*.*", 0, 1, 0, 1, "", "Second Folder;Third Folder")I mentioned above that you need to use the "files and folders" search option to get the $sExclude_List_Folder parameter to work. If you notice I have added a "" at the end of the initial path - that means that all folders returned by the UDF also end in "". So you can very easily ignore them when you loop through the array reading the file names. All clear? M23 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
address Posted February 18, 2012 Posted February 18, 2012 Melba23This gave me empty txt file#include <RecFileListToArray.au3> #include <File.au3> $aFiles = _RecFileListToArray("d:MiscPics", "*.jpg; *.png; *.gif", 0, 1, 0, 2, "", "d:MiscPicsOld comp"); second number with or without subfolders $hFile = FileOpen(@ScriptDir & "1.txt",1) _FileWriteFromArray($hFile, $aFiles, 1) FileClose($hFile) ;$aList = _RecFileListToArray("N:Test", "*.*", 0, 1, 0, 1, "", "Second Folder;Third Folder") ;I mentioned above that you need to use the "files and folders" search option to get the $sExclude_List_Folder parameter to work. ;If you notice I have added a "" at the end of the initial path - that means that all folders returned by the UDF also end in "". ; So you can very easily ignore them when you loop through the array reading the file names.
Moderators Melba23 Posted February 18, 2012 Author Moderators Posted February 18, 2012 address, Try this: $aFiles = _RecFileListToArray("d:MiscPics", "*.jpg; *.png; *.gif", 0, 1, 0, 2, "", "Old comp") You only need the folder name, not the complete path. M23 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
address Posted February 18, 2012 Posted February 18, 2012 (edited) Melba23that's beautiful, thanks so much.Is it possible to mask files by their size? Edited February 18, 2012 by address
Moderators Melba23 Posted February 18, 2012 Author Moderators Posted February 18, 2012 address,My pleasure. I am afraid you cannot mask by size. You would need to loop through the array of all files produced by _RecFileListToArray and use FileGetSize on each one. M23 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
StungStang Posted March 7, 2012 Posted March 7, 2012 @Melba23Is possible to get some kind of progress bar in that udf? I'm trying to do that, in my case i want to search by file search by extension on the whole hard drive. The search work good but as you can image the function take some minute to retrive the resoult. That's why i want to add a simple progress bar, something like:($Current_Number_Of_Searched_File * 100)/$Total_File_on_HDBut i have no idea on how to set that code in your udf Hi and thank's for the help
Moderators Melba23 Posted March 7, 2012 Author Moderators Posted March 7, 2012 StungStang, The UDF returns nothing until it has completed its search so there is no possibility of using it to run a progress bar at present. Anyway as you would need to run some kind of recursive search on the path to find the total number of files to use as a base value before running the UDF to search the drive, you would effectively be running the UDF twice to produce a progress bar - not very efficient. I would suggest using a marquee type progress so that at least the user knows that something is going on: #include <GUIConstantsEx.au3> #include <ProgressConstants.au3> $hGUI = GUICreate("Test", 500, 500) GUICtrlCreateProgress(10, 10, 400, 20, $PBS_MARQUEE) GUICtrlSendMsg(-1, $PBM_SETMARQUEE, True, 50) ; final parameter is update time in ms GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd I hope that helps. M23 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
StungStang Posted March 7, 2012 Posted March 7, 2012 I think that i've found a working soluction: This is the new code: expandcollapse popupFunc _RecFileListToArray($sInitialPath, $sInclude_List = "*", $iReturn = 0, $iRecur = 0, $iSort = 0, $iReturnPath = 1, $sExclude_List = "", $sExclude_List_Folder = "", $sTotal_File = 0, $sProgress = "") Local $asReturnList[100] = [0], $asFileMatchList[100] = [0], $asRootFileMatchList[100] = [0], $asFolderMatchList[100] = [0], $asFolderSearchList[100] = [1] Local $sFolderSlash = "", $iMaxLevel, $sInclude_File_Mask, $sExclude_File_Mask, $sInclude_Folder_Mask = ".+", $sExclude_Folder_Mask = ":" Local $hSearch, $fFolder, $sRetPath = "", $sCurrentPath, $sName Local $asFolderFileSectionList[100][2] = [[0, 0]], $sFolderToFind, $iFileSectionStartIndex, $iFileSectionEndIndex Global $sCurrent_File = 0 ; Check for valid path If Not FileExists($sInitialPath) Then Return SetError(1, 1, "") ; Check if folders should have trailing \ and ensure that initial path does have one If StringRight($sInitialPath, 1) = "\" Then $sFolderSlash = "\" Else $sInitialPath = $sInitialPath & "\" EndIf ; Add path to folder search list $asFolderSearchList[1] = $sInitialPath ; Check for valid recur value If $iRecur > 1 Or Not IsInt($iRecur) Then Return SetError(1, 4, "") ; If required, determine \ count for max recursive level setting If $iRecur < 0 Then StringReplace($sInitialPath, "\", "", 2) $iMaxLevel = @extended - $iRecur EndIf ; Create Include mask for files If $sInclude_List = "*" Then $sInclude_File_Mask = ".+" Else If Not _RFLTA_ListToMask($sInclude_File_Mask, $sInclude_List) Then Return SetError(1, 2, "") EndIf ; 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 ;Case Else ; All folders match EndSwitch ;Case 1 ; All folders match Case 2 ; Folders affected by mask $sInclude_Folder_Mask = $sInclude_File_Mask EndSwitch ; Create Exclude List mask for files If $sExclude_List = "" Then $sExclude_File_Mask = ":" ; Set unmatchable mask Else If Not _RFLTA_ListToMask($sExclude_File_Mask, $sExclude_List) Then Return SetError(1, 7, "") EndIf ; Set Exclude mask for folders Switch $iReturn Case 0 ; Folders affected by mask if not recursive Switch $iRecur Case 0 ; Folders match mask for compatibility $sExclude_Folder_Mask = $sExclude_File_Mask Case Else ; Exclude defined folders as set in extended If $sExclude_List_Folder <> "" Then If Not _RFLTA_ListToMask($sExclude_Folder_Mask, $sExclude_List_Folder) Then Return SetError(1, 8, "") EndIf EndSwitch ;Case 1 ; All folders match Case 2 ; Folders affected by normal mask $sExclude_Folder_Mask = $sExclude_File_Mask EndSwitch ; Verify other parameters If Not ($iReturn = 0 Or $iReturn = 1 Or $iReturn = 2) Then Return SetError(1, 3, "") If Not ($iSort = 0 Or $iSort = 1 Or $iSort = 2) Then Return SetError(1, 5, "") If Not ($iReturnPath = 0 Or $iReturnPath = 1 Or $iReturnPath = 2) Then Return SetError(1, 6, "") ; 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, $sInitialPath, "") Case 2 ; Full path $sRetPath = $sCurrentPath EndSwitch ; Get search handle $hSearch = FileFindFirstFile($sCurrentPath & "*") ; 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 _RFLTA_AddToList($asFolderFileSectionList, $sRetPath, $asFileMatchList[0] + 1) EndIf ; If folder empty move to next in list If $hSearch = -1 Then ContinueLoop EndIf ; Search folder While 1 If $sTotal_File > 0 And $sProgress <> "" Then _RFLTA_Progress($sProgress,$sTotal_File) $sName = FileFindNextFile($hSearch) ; Check for end of folder If @error Then ExitLoop EndIf ; ; Set subfolder flag - @extended set in 3.3.1.1 + $fFolder = @extended ; If folder then check whether to add to search list If $fFolder Then Select Case $iRecur < 0 ; Check recur depth StringReplace($sCurrentPath, "\", "", 0, 2) 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 _RFLTA_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 $fFolder Then If StringRegExp($sName, $sInclude_Folder_Mask) And Not StringRegExp($sName, $sExclude_Folder_Mask) Then _RFLTA_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 = $sInitialPath Then _RFLTA_AddToList($asRootFileMatchList, $sRetPath & $sName) Else _RFLTA_AddToList($asFileMatchList, $sRetPath & $sName) EndIf EndIf EndIf Else ; Save directly in return list If $fFolder Then If $iReturn <> 1 And StringRegExp($sName, $sInclude_Folder_Mask) And Not StringRegExp($sName, $sExclude_Folder_Mask) Then _RFLTA_AddToList($asReturnList, $sRetPath & $sName & $sFolderSlash) EndIf Else If $iReturn <> 2 And StringRegExp($sName, $sInclude_File_Mask) And Not StringRegExp($sName, $sExclude_File_Mask) Then _RFLTA_AddToList($asReturnList, $sRetPath & $sName) EndIf EndIf EndIf WEnd ; Close current search FileClose($hSearch) WEnd If $iSort Then ; Check if any file/folders have been added depending on required return Switch $iReturn Case 0 ; If no folders then number of files is immaterial If $asRootFileMatchList[0] = 0 And $asFolderMatchList[0] = 0 Then Return SetError(1, 9, "") Case 1 If $asRootFileMatchList[0] = 0 And $asFileMatchList[0] = 0 Then Return SetError(1, 9, "") Case 2 If $asFolderMatchList[0] = 0 Then Return SetError(1, 9, "") EndSwitch Switch $iReturn Case 2 ; Folders only ; Correctly size folder match list ReDim $asFolderMatchList[$asFolderMatchList[0] + 1] ; Copy size folder match array $asReturnList = $asFolderMatchList ; Simple sort list _RFLTA_ArraySort($asReturnList) Case 1 ; Files only If $iReturnPath = 0 Then ; names only so simple sort suffices ; Combine file match lists _RFLTA_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList) ; Simple sort combined file list _RFLTA_ArraySort($asReturnList) Else ; Combine sorted file match lists _RFLTA_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList, 1) EndIf Case 0 ; Both files and folders If $iReturnPath = 0 Then ; names only so simple sort suffices ; Combine file match lists _RFLTA_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] _RFLTA_ArrayConcatenate($asReturnList, $asFolderMatchList) ; Simple sort final list _RFLTA_ArraySort($asReturnList) 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 _RFLTA_ArraySort($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 _RFLTA_ArraySort($asFolderMatchList, 1, $asFolderMatchList[0]) ; Work through folder list For $i = 1 To $asFolderMatchList[0] ; Format folder name for search If $sFolderSlash Then $sFolderToFind = $asFolderMatchList[$i] Else $sFolderToFind = $asFolderMatchList[$i] & "\" EndIf ; Find folder in FolderFileSectionList For $j = 1 To $asFolderFileSectionList[0][0] If $sFolderToFind = $asFolderFileSectionList[$j][0] Then ExitLoop Next ; 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 _RFLTA_ArraySort($asFileMatchList, $iFileSectionStartIndex, $iFileSectionEndIndex) EndIf ; Add folder to return list $asReturnList[$iNextInsertionIndex] = $asFolderMatchList[$i] $iNextInsertionIndex += 1 ; Add files to return list For $j = $iFileSectionStartIndex To $iFileSectionEndIndex $asReturnList[$iNextInsertionIndex] = $asFileMatchList[$j] $iNextInsertionIndex += 1 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 ;==>_RecFileListToArray Now the function have 2 new value: $sTotal_File And $sProgress. In the first you have to inserct the total file present in the directory/drive in the second value you have to I've added this new function: Func _RFLTA_Progress($vProgress = "",$sTotal = 0) $sCurrent_File = $sCurrent_File + 1 Return GUICtrlSetData($vProgress,$sCurrent_File *100/$sTotal) EndFunc This is a sample code : expandcollapse popup#include <GUIConstantsEx.au3> #include <ProgressConstants.au3> #include <Array.au3> $hGUI = GUICreate("Test", 500, 500) $Progress1 = GUICtrlCreateProgress(10, 10, 400, 20) GUISetState() $Dir_Info = DirGetSize("C:\", 1) $File_Number = $Dir_Info[1] $Search_File = _RecFileListToArray("C:\", "*.tmp", 1, 1, 0, 2, "", "", $File_Number, $Progress1) If IsArray($Search_File) Then MsgBox (0,"Done","Item found!") _ArrayDisplay($Search_File) EndIf While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Func _RecFileListToArray($sInitialPath, $sInclude_List = "*", $iReturn = 0, $iRecur = 0, $iSort = 0, $iReturnPath = 1, $sExclude_List = "", $sExclude_List_Folder = "", $sTotal_File = 0, $sProgress = "") Local $asReturnList[100] = [0], $asFileMatchList[100] = [0], $asRootFileMatchList[100] = [0], $asFolderMatchList[100] = [0], $asFolderSearchList[100] = [1] Local $sFolderSlash = "", $iMaxLevel, $sInclude_File_Mask, $sExclude_File_Mask, $sInclude_Folder_Mask = ".+", $sExclude_Folder_Mask = ":" Local $hSearch, $fFolder, $sRetPath = "", $sCurrentPath, $sName Local $asFolderFileSectionList[100][2] = [[0, 0]], $sFolderToFind, $iFileSectionStartIndex, $iFileSectionEndIndex Global $sCurrent_File = 0 ; Check for valid path If Not FileExists($sInitialPath) Then Return SetError(1, 1, "") ; Check if folders should have trailing \ and ensure that initial path does have one If StringRight($sInitialPath, 1) = "\" Then $sFolderSlash = "\" Else $sInitialPath = $sInitialPath & "\" EndIf ; Add path to folder search list $asFolderSearchList[1] = $sInitialPath ; Check for valid recur value If $iRecur > 1 Or Not IsInt($iRecur) Then Return SetError(1, 4, "") ; If required, determine \ count for max recursive level setting If $iRecur < 0 Then StringReplace($sInitialPath, "\", "", 2) $iMaxLevel = @extended - $iRecur EndIf ; Create Include mask for files If $sInclude_List = "*" Then $sInclude_File_Mask = ".+" Else If Not _RFLTA_ListToMask($sInclude_File_Mask, $sInclude_List) Then Return SetError(1, 2, "") EndIf ; 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 ;Case Else ; All folders match EndSwitch ;Case 1 ; All folders match Case 2 ; Folders affected by mask $sInclude_Folder_Mask = $sInclude_File_Mask EndSwitch ; Create Exclude List mask for files If $sExclude_List = "" Then $sExclude_File_Mask = ":" ; Set unmatchable mask Else If Not _RFLTA_ListToMask($sExclude_File_Mask, $sExclude_List) Then Return SetError(1, 7, "") EndIf ; Set Exclude mask for folders Switch $iReturn Case 0 ; Folders affected by mask if not recursive Switch $iRecur Case 0 ; Folders match mask for compatibility $sExclude_Folder_Mask = $sExclude_File_Mask Case Else ; Exclude defined folders as set in extended If $sExclude_List_Folder <> "" Then If Not _RFLTA_ListToMask($sExclude_Folder_Mask, $sExclude_List_Folder) Then Return SetError(1, 8, "") EndIf EndSwitch ;Case 1 ; All folders match Case 2 ; Folders affected by normal mask $sExclude_Folder_Mask = $sExclude_File_Mask EndSwitch ; Verify other parameters If Not ($iReturn = 0 Or $iReturn = 1 Or $iReturn = 2) Then Return SetError(1, 3, "") If Not ($iSort = 0 Or $iSort = 1 Or $iSort = 2) Then Return SetError(1, 5, "") If Not ($iReturnPath = 0 Or $iReturnPath = 1 Or $iReturnPath = 2) Then Return SetError(1, 6, "") ; 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, $sInitialPath, "") Case 2 ; Full path $sRetPath = $sCurrentPath EndSwitch ; Get search handle $hSearch = FileFindFirstFile($sCurrentPath & "*") ; 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 _RFLTA_AddToList($asFolderFileSectionList, $sRetPath, $asFileMatchList[0] + 1) EndIf ; If folder empty move to next in list If $hSearch = -1 Then ContinueLoop EndIf ; Search folder While 1 If $sTotal_File > 0 And $sProgress <> "" Then _RFLTA_Progress($sProgress, $sTotal_File) $sName = FileFindNextFile($hSearch) ; Check for end of folder If @error Then ExitLoop EndIf ; ; Set subfolder flag - @extended set in 3.3.1.1 + $fFolder = @extended ; If folder then check whether to add to search list If $fFolder Then Select Case $iRecur < 0 ; Check recur depth StringReplace($sCurrentPath, "\", "", 0, 2) 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 _RFLTA_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 $fFolder Then If StringRegExp($sName, $sInclude_Folder_Mask) And Not StringRegExp($sName, $sExclude_Folder_Mask) Then _RFLTA_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 = $sInitialPath Then _RFLTA_AddToList($asRootFileMatchList, $sRetPath & $sName) Else _RFLTA_AddToList($asFileMatchList, $sRetPath & $sName) EndIf EndIf EndIf Else ; Save directly in return list If $fFolder Then If $iReturn <> 1 And StringRegExp($sName, $sInclude_Folder_Mask) And Not StringRegExp($sName, $sExclude_Folder_Mask) Then _RFLTA_AddToList($asReturnList, $sRetPath & $sName & $sFolderSlash) EndIf Else If $iReturn <> 2 And StringRegExp($sName, $sInclude_File_Mask) And Not StringRegExp($sName, $sExclude_File_Mask) Then _RFLTA_AddToList($asReturnList, $sRetPath & $sName) EndIf EndIf EndIf WEnd ; Close current search FileClose($hSearch) WEnd If $iSort Then ; Check if any file/folders have been added depending on required return Switch $iReturn Case 0 ; If no folders then number of files is immaterial If $asRootFileMatchList[0] = 0 And $asFolderMatchList[0] = 0 Then Return SetError(1, 9, "") Case 1 If $asRootFileMatchList[0] = 0 And $asFileMatchList[0] = 0 Then Return SetError(1, 9, "") Case 2 If $asFolderMatchList[0] = 0 Then Return SetError(1, 9, "") EndSwitch Switch $iReturn Case 2 ; Folders only ; Correctly size folder match list ReDim $asFolderMatchList[$asFolderMatchList[0] + 1] ; Copy size folder match array $asReturnList = $asFolderMatchList ; Simple sort list _RFLTA_ArraySort($asReturnList) Case 1 ; Files only If $iReturnPath = 0 Then ; names only so simple sort suffices ; Combine file match lists _RFLTA_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList) ; Simple sort combined file list _RFLTA_ArraySort($asReturnList) Else ; Combine sorted file match lists _RFLTA_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList, 1) EndIf Case 0 ; Both files and folders If $iReturnPath = 0 Then ; names only so simple sort suffices ; Combine file match lists _RFLTA_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] _RFLTA_ArrayConcatenate($asReturnList, $asFolderMatchList) ; Simple sort final list _RFLTA_ArraySort($asReturnList) 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 _RFLTA_ArraySort($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 _RFLTA_ArraySort($asFolderMatchList, 1, $asFolderMatchList[0]) ; Work through folder list For $i = 1 To $asFolderMatchList[0] ; Format folder name for search If $sFolderSlash Then $sFolderToFind = $asFolderMatchList[$i] Else $sFolderToFind = $asFolderMatchList[$i] & "\" EndIf ; Find folder in FolderFileSectionList For $j = 1 To $asFolderFileSectionList[0][0] If $sFolderToFind = $asFolderFileSectionList[$j][0] Then ExitLoop Next ; 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 _RFLTA_ArraySort($asFileMatchList, $iFileSectionStartIndex, $iFileSectionEndIndex) EndIf ; Add folder to return list $asReturnList[$iNextInsertionIndex] = $asFolderMatchList[$i] $iNextInsertionIndex += 1 ; Add files to return list For $j = $iFileSectionStartIndex To $iFileSectionEndIndex $asReturnList[$iNextInsertionIndex] = $asFileMatchList[$j] $iNextInsertionIndex += 1 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 ;==>_RecFileListToArray Func _RFLTA_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*", ";"), 3), ";", "|") ; Convert to SRE pattern $sList = StringReplace(StringReplace(StringRegExpReplace($sList, "[][$^.{}()+\-]", "\\$0"), "?", "."), "*", ".*?") ; Add prefix and suffix $sMask = "(?i)^(" & $sList & ")\z" Return 1 EndFunc ;==>_RFLTA_ListToMask Func _RFLTA_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 ;==>_RFLTA_AddToList Func _RFLTA_AddFileLists(ByRef $asTarget, $asSource_1, $asSource_2, $iSort = 0) ; Correctly size root file match array ReDim $asSource_1[$asSource_1[0] + 1] ; Simple sort root file match array if required If $iSort = 1 Then _RFLTA_ArraySort($asSource_1) ; Copy root file match array $asTarget = $asSource_1 ; Add file match count $asTarget[0] += $asSource_2[0] ; Correctly size file match array ReDim $asSource_2[$asSource_2[0] + 1] ; Simple sort file match array if required If $iSort = 1 Then _RFLTA_ArraySort($asSource_2) ; Add file match array _RFLTA_ArrayConcatenate($asTarget, $asSource_2) EndFunc ;==>_RFLTA_AddFileLists Func _RFLTA_FileListSearch(Const ByRef $avArray, $vValue, $iIndex, $sSlash) Local $aRet[2] ; Add final \ if required If Not $sSlash Then $vValue &= "\" ; Start by getting top match - search down from start index For $i = $iIndex To $avArray[0] ; SRE gives path less filename If StringRegExpReplace($avArray[$i], "(^.*\\)(.*)", "\1") = $vValue Then ExitLoop Next If $i > $avArray[0] Then ; No match found so look from start index upwards If $iIndex = $avArray[0] Then $iIndex -= 1 For $i = $iIndex + 1 To 1 Step -1 If StringRegExpReplace($avArray[$i], "(^.*\\)(.*)", "\1") = $vValue Then ExitLoop Next ; If still no match - return " nothing found" for empty folder If $i = 0 Then Return SetError(1, 0, "") ; Set index of bottom file $aRet[1] = $i ; Now look for top match For $i = $aRet[1] To 1 Step -1 If StringRegExpReplace($avArray[$i], "(^.*\\)(.*)", "\1") <> $vValue Then ExitLoop Next ; Set top match $aRet[0] = $i + 1 Else ; Set index of top associated file $aRet[0] = $i ; Now look for bottom match - find first file which does not match For $i = $aRet[0] To $avArray[0] If StringRegExpReplace($avArray[$i], "(^.*\\)(.*)", "\1") <> $vValue Then ExitLoop Next ; Set bottom match $aRet[1] = $i - 1 EndIf Return $aRet EndFunc ;==>_RFLTA_FileListSearch Func _RFLTA_ArraySort(ByRef $avArray, $iStart = 1, $iEnd = -99) If $iEnd = -99 Then $iEnd = UBound($avArray) - 1 _RFLTA_QuickSort($avArray, $iStart, $iEnd) EndFunc ;==>_RFLTA_ArraySort Func _RFLTA_QuickSort(ByRef $avArray, ByRef $iStart, ByRef $iEnd) Local $vTmp If ($iEnd - $iStart) < 15 Then Local $i, $j, $vCur For $i = $iStart + 1 To $iEnd $vTmp = $avArray[$i] If IsNumber($vTmp) Then For $j = $i - 1 To $iStart Step -1 $vCur = $avArray[$j] If ($vTmp >= $vCur And IsNumber($vCur)) Or (Not IsNumber($vCur) And StringCompare($vTmp, $vCur) >= 0) Then ExitLoop $avArray[$j + 1] = $vCur Next Else For $j = $i - 1 To $iStart Step -1 If (StringCompare($vTmp, $avArray[$j]) >= 0) Then ExitLoop $avArray[$j + 1] = $avArray[$j] Next EndIf $avArray[$j + 1] = $vTmp Next Return EndIf Local $L = $iStart, $R = $iEnd, $vPivot = $avArray[Int(($iStart + $iEnd) / 2)], $fNum = IsNumber($vPivot) Do If $fNum Then While ($avArray[$L] < $vPivot And IsNumber($avArray[$L])) Or (Not IsNumber($avArray[$L]) And StringCompare($avArray[$L], $vPivot) < 0) $L += 1 WEnd While ($avArray[$R] > $vPivot And IsNumber($avArray[$R])) Or (Not IsNumber($avArray[$R]) And StringCompare($avArray[$R], $vPivot) > 0) $R -= 1 WEnd Else While (StringCompare($avArray[$L], $vPivot) < 0) $L += 1 WEnd While (StringCompare($avArray[$R], $vPivot) > 0) $R -= 1 WEnd EndIf If $L <= $R Then $vTmp = $avArray[$L] $avArray[$L] = $avArray[$R] $avArray[$R] = $vTmp $L += 1 $R -= 1 EndIf Until $L > $R _RFLTA_QuickSort($avArray, $iStart, $R) _RFLTA_QuickSort($avArray, $L, $iEnd) EndFunc ;==>_RFLTA_QuickSort Func _RFLTA_ArrayConcatenate(ByRef $avArrayTarget, Const ByRef $avArraySource) Local $iUBoundTarget = UBound($avArrayTarget) - 1, $iUBoundSource = UBound($avArraySource) ReDim $avArrayTarget[$iUBoundTarget + $iUBoundSource] For $i = 1 To $iUBoundSource - 1 $avArrayTarget[$iUBoundTarget + $i] = $avArraySource[$i] Next EndFunc ;==>_RFLTA_ArrayConcatenate Func _RFLTA_Progress($vProgress = "", $sTotal = 0) $sCurrent_File = $sCurrent_File + 1 Return GUICtrlSetData($vProgress, $sCurrent_File * 100 / $sTotal) EndFunc ;==>_RFLTA_Progress The only problem is that DirGetSize() is too slow at first run when it have to count the total file in a directory/drive. Do you know a soluction to speed up that? Another question, do you think is possible to be stoopable the _RecFileListToArray(), for example if an user see that the process can take too much time it can simply "cancel" the search process. Is possible? Hi
Moderators Melba23 Posted March 7, 2012 Author Moderators Posted March 7, 2012 StungStang,Please feel free to amend the code as you want - but remember you then have to support it! The only problem is that DirGetSize() is too slow at first run when it have to count the total file in a directory/drive. Do you know a soluction to speed up that?That is the very problem I mentioned above - you need 2 searches to make the progress bar work- very inefficient and slow. do you think is possible to be stoopable the _RecFileListToArrayAbsolutely, there are many loops and so the function can be interrupted easily. Take a look at the Interrupting a running function tutorial in the Wiki - that shows you several ways to do it. Please ask again if you run into difficulty integrating code form the tutorial into the function. M23 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
StungStang Posted March 7, 2012 Posted March 7, 2012 (edited) I don't know if i have do it done this is my code now: expandcollapse popup#include <GUIConstantsEx.au3> #include <ProgressConstants.au3> #include <Array.au3> Local $BreaK = 0 $hGUI = GUICreate("Test", 500, 500) $Progress1 = GUICtrlCreateProgress(10, 10, 400, 20) $StopIT = GUICtrlCreateButton("Search", 72, 136, 363, 73) GUISetState(@SW_SHOW) $Dir_Info = DirGetSize("C:", 1) $File_Number = $Dir_Info[1] While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $StopIT If GUICtrlRead($StopIT) == "Search" Then GUICtrlSetData($StopIT, "Cancel") Opt("GUIOnEventMode", 1) GUICtrlSetOnEvent($StopIT, "_Break") $Search_File = _RecFileListToArray("C:", "*.tmp", 1, 1, 0, 2, "", "", $File_Number, $Progress1) If $BreaK = 0 Then Opt("GUIOnEventMode",0) If IsArray($Search_File) Then MsgBox(0, "Done", "Item found!") _ArrayDisplay($Search_File) EndIf Else $BreaK = 0 Opt("GUIOnEventMode",0) MsgBox(0, "OK", "You have cancelled the search :(") EndIf GUICtrlSetData($StopIT, "Search") Else $File_Searching = False GUICtrlSetData($StopIT, "Search") EndIf EndSwitch WEnd Func _Break() $BreaK = 1 EndFunc ;==>_Break Func _RecFileListToArray($sInitialPath, $sInclude_List = "*", $iReturn = 0, $iRecur = 0, $iSort = 0, $iReturnPath = 1, $sExclude_List = "", $sExclude_List_Folder = "", $sTotal_File = 0, $sProgress = "") Local $asReturnList[100] = [0], $asFileMatchList[100] = [0], $asRootFileMatchList[100] = [0], $asFolderMatchList[100] = [0], $asFolderSearchList[100] = [1] Local $sFolderSlash = "", $iMaxLevel, $sInclude_File_Mask, $sExclude_File_Mask, $sInclude_Folder_Mask = ".+", $sExclude_Folder_Mask = ":" Local $hSearch, $fFolder, $sRetPath = "", $sCurrentPath, $sName Local $asFolderFileSectionList[100][2] = [[0, 0]], $sFolderToFind, $iFileSectionStartIndex, $iFileSectionEndIndex Global $sCurrent_File = 0 ; Check for valid path If Not FileExists($sInitialPath) Then Return SetError(1, 1, "") ; Check if folders should have trailing and ensure that initial path does have one If StringRight($sInitialPath, 1) = "" Then $sFolderSlash = "" Else $sInitialPath = $sInitialPath & "" EndIf ; Add path to folder search list $asFolderSearchList[1] = $sInitialPath ; Check for valid recur value If $iRecur > 1 Or Not IsInt($iRecur) Then Return SetError(1, 4, "") ; If required, determine count for max recursive level setting If $iRecur < 0 Then StringReplace($sInitialPath, "", "", 2) $iMaxLevel = @extended - $iRecur EndIf ; Create Include mask for files If $sInclude_List = "*" Then $sInclude_File_Mask = ".+" Else If Not _RFLTA_ListToMask($sInclude_File_Mask, $sInclude_List) Then Return SetError(1, 2, "") EndIf ; 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 ;Case Else ; All folders match EndSwitch ;Case 1 ; All folders match Case 2 ; Folders affected by mask $sInclude_Folder_Mask = $sInclude_File_Mask EndSwitch ; Create Exclude List mask for files If $sExclude_List = "" Then $sExclude_File_Mask = ":" ; Set unmatchable mask Else If Not _RFLTA_ListToMask($sExclude_File_Mask, $sExclude_List) Then Return SetError(1, 7, "") EndIf ; Set Exclude mask for folders Switch $iReturn Case 0 ; Folders affected by mask if not recursive Switch $iRecur Case 0 ; Folders match mask for compatibility $sExclude_Folder_Mask = $sExclude_File_Mask Case Else ; Exclude defined folders as set in extended If $sExclude_List_Folder <> "" Then If Not _RFLTA_ListToMask($sExclude_Folder_Mask, $sExclude_List_Folder) Then Return SetError(1, 8, "") EndIf EndSwitch ;Case 1 ; All folders match Case 2 ; Folders affected by normal mask $sExclude_Folder_Mask = $sExclude_File_Mask EndSwitch ; Verify other parameters If Not ($iReturn = 0 Or $iReturn = 1 Or $iReturn = 2) Then Return SetError(1, 3, "") If Not ($iSort = 0 Or $iSort = 1 Or $iSort = 2) Then Return SetError(1, 5, "") If Not ($iReturnPath = 0 Or $iReturnPath = 1 Or $iReturnPath = 2) Then Return SetError(1, 6, "") ; Search within listed folders While $asFolderSearchList[0] > 0 If $BreaK = 1 Then ConsoleWrite("Stopped") ;Debug purpose only If $sProgress <> "" Then GUICtrlSetData($sProgress, 0) ;Reset the progress bar ExitLoop Return EndIf ; 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, $sInitialPath, "") Case 2 ; Full path $sRetPath = $sCurrentPath EndSwitch ; Get search handle $hSearch = FileFindFirstFile($sCurrentPath & "*") ; 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 _RFLTA_AddToList($asFolderFileSectionList, $sRetPath, $asFileMatchList[0] + 1) EndIf ; If folder empty move to next in list If $hSearch = -1 Then ContinueLoop EndIf ; Search folder While 1 If $sTotal_File > 0 And $sProgress <> "" Then _RFLTA_Progress($sProgress, $sTotal_File) $sName = FileFindNextFile($hSearch) ; Check for end of folder If @error Then ExitLoop EndIf ; ; Set subfolder flag - @extended set in 3.3.1.1 + $fFolder = @extended ; If folder then check whether to add to search list If $fFolder Then Select Case $iRecur < 0 ; Check recur depth StringReplace($sCurrentPath, "", "", 0, 2) 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 _RFLTA_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 $fFolder Then If StringRegExp($sName, $sInclude_Folder_Mask) And Not StringRegExp($sName, $sExclude_Folder_Mask) Then _RFLTA_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 = $sInitialPath Then _RFLTA_AddToList($asRootFileMatchList, $sRetPath & $sName) Else _RFLTA_AddToList($asFileMatchList, $sRetPath & $sName) EndIf EndIf EndIf Else ; Save directly in return list If $fFolder Then If $iReturn <> 1 And StringRegExp($sName, $sInclude_Folder_Mask) And Not StringRegExp($sName, $sExclude_Folder_Mask) Then _RFLTA_AddToList($asReturnList, $sRetPath & $sName & $sFolderSlash) EndIf Else If $iReturn <> 2 And StringRegExp($sName, $sInclude_File_Mask) And Not StringRegExp($sName, $sExclude_File_Mask) Then _RFLTA_AddToList($asReturnList, $sRetPath & $sName) EndIf EndIf EndIf WEnd ; Close current search FileClose($hSearch) WEnd If $iSort Then ; Check if any file/folders have been added depending on required return Switch $iReturn Case 0 ; If no folders then number of files is immaterial If $asRootFileMatchList[0] = 0 And $asFolderMatchList[0] = 0 Then Return SetError(1, 9, "") Case 1 If $asRootFileMatchList[0] = 0 And $asFileMatchList[0] = 0 Then Return SetError(1, 9, "") Case 2 If $asFolderMatchList[0] = 0 Then Return SetError(1, 9, "") EndSwitch Switch $iReturn Case 2 ; Folders only ; Correctly size folder match list ReDim $asFolderMatchList[$asFolderMatchList[0] + 1] ; Copy size folder match array $asReturnList = $asFolderMatchList ; Simple sort list _RFLTA_ArraySort($asReturnList) Case 1 ; Files only If $iReturnPath = 0 Then ; names only so simple sort suffices ; Combine file match lists _RFLTA_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList) ; Simple sort combined file list _RFLTA_ArraySort($asReturnList) Else ; Combine sorted file match lists _RFLTA_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList, 1) EndIf Case 0 ; Both files and folders If $iReturnPath = 0 Then ; names only so simple sort suffices ; Combine file match lists _RFLTA_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] _RFLTA_ArrayConcatenate($asReturnList, $asFolderMatchList) ; Simple sort final list _RFLTA_ArraySort($asReturnList) 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 _RFLTA_ArraySort($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 _RFLTA_ArraySort($asFolderMatchList, 1, $asFolderMatchList[0]) ; Work through folder list For $i = 1 To $asFolderMatchList[0] ; Format folder name for search If $sFolderSlash Then $sFolderToFind = $asFolderMatchList[$i] Else $sFolderToFind = $asFolderMatchList[$i] & "" EndIf ; Find folder in FolderFileSectionList For $j = 1 To $asFolderFileSectionList[0][0] If $sFolderToFind = $asFolderFileSectionList[$j][0] Then ExitLoop Next ; 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 _RFLTA_ArraySort($asFileMatchList, $iFileSectionStartIndex, $iFileSectionEndIndex) EndIf ; Add folder to return list $asReturnList[$iNextInsertionIndex] = $asFolderMatchList[$i] $iNextInsertionIndex += 1 ; Add files to return list For $j = $iFileSectionStartIndex To $iFileSectionEndIndex $asReturnList[$iNextInsertionIndex] = $asFileMatchList[$j] $iNextInsertionIndex += 1 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 ;==>_RecFileListToArray Func _RFLTA_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*", ";"), 3), ";", "|") ; Convert to SRE pattern $sList = StringReplace(StringReplace(StringRegExpReplace($sList, "[][$^.{}()+-]", "$0"), "?", "."), "*", ".*?") ; Add prefix and suffix $sMask = "(?i)^(" & $sList & ")z" Return 1 EndFunc ;==>_RFLTA_ListToMask Func _RFLTA_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 ;==>_RFLTA_AddToList Func _RFLTA_AddFileLists(ByRef $asTarget, $asSource_1, $asSource_2, $iSort = 0) ; Correctly size root file match array ReDim $asSource_1[$asSource_1[0] + 1] ; Simple sort root file match array if required If $iSort = 1 Then _RFLTA_ArraySort($asSource_1) ; Copy root file match array $asTarget = $asSource_1 ; Add file match count $asTarget[0] += $asSource_2[0] ; Correctly size file match array ReDim $asSource_2[$asSource_2[0] + 1] ; Simple sort file match array if required If $iSort = 1 Then _RFLTA_ArraySort($asSource_2) ; Add file match array _RFLTA_ArrayConcatenate($asTarget, $asSource_2) EndFunc ;==>_RFLTA_AddFileLists Func _RFLTA_FileListSearch(Const ByRef $avArray, $vValue, $iIndex, $sSlash) Local $aRet[2] ; Add final if required If Not $sSlash Then $vValue &= "" ; Start by getting top match - search down from start index For $i = $iIndex To $avArray[0] ; SRE gives path less filename If StringRegExpReplace($avArray[$i], "(^.*)(.*)", "1") = $vValue Then ExitLoop Next If $i > $avArray[0] Then ; No match found so look from start index upwards If $iIndex = $avArray[0] Then $iIndex -= 1 For $i = $iIndex + 1 To 1 Step -1 If StringRegExpReplace($avArray[$i], "(^.*)(.*)", "1") = $vValue Then ExitLoop Next ; If still no match - return " nothing found" for empty folder If $i = 0 Then Return SetError(1, 0, "") ; Set index of bottom file $aRet[1] = $i ; Now look for top match For $i = $aRet[1] To 1 Step -1 If StringRegExpReplace($avArray[$i], "(^.*)(.*)", "1") <> $vValue Then ExitLoop Next ; Set top match $aRet[0] = $i + 1 Else ; Set index of top associated file $aRet[0] = $i ; Now look for bottom match - find first file which does not match For $i = $aRet[0] To $avArray[0] If StringRegExpReplace($avArray[$i], "(^.*)(.*)", "1") <> $vValue Then ExitLoop Next ; Set bottom match $aRet[1] = $i - 1 EndIf Return $aRet EndFunc ;==>_RFLTA_FileListSearch Func _RFLTA_ArraySort(ByRef $avArray, $iStart = 1, $iEnd = -99) If $iEnd = -99 Then $iEnd = UBound($avArray) - 1 _RFLTA_QuickSort($avArray, $iStart, $iEnd) EndFunc ;==>_RFLTA_ArraySort Func _RFLTA_QuickSort(ByRef $avArray, ByRef $iStart, ByRef $iEnd) Local $vTmp If ($iEnd - $iStart) < 15 Then Local $i, $j, $vCur For $i = $iStart + 1 To $iEnd $vTmp = $avArray[$i] If IsNumber($vTmp) Then For $j = $i - 1 To $iStart Step -1 $vCur = $avArray[$j] If ($vTmp >= $vCur And IsNumber($vCur)) Or (Not IsNumber($vCur) And StringCompare($vTmp, $vCur) >= 0) Then ExitLoop $avArray[$j + 1] = $vCur Next Else For $j = $i - 1 To $iStart Step -1 If (StringCompare($vTmp, $avArray[$j]) >= 0) Then ExitLoop $avArray[$j + 1] = $avArray[$j] Next EndIf $avArray[$j + 1] = $vTmp Next Return EndIf Local $L = $iStart, $R = $iEnd, $vPivot = $avArray[Int(($iStart + $iEnd) / 2)], $fNum = IsNumber($vPivot) Do If $fNum Then While ($avArray[$L] < $vPivot And IsNumber($avArray[$L])) Or (Not IsNumber($avArray[$L]) And StringCompare($avArray[$L], $vPivot) < 0) $L += 1 WEnd While ($avArray[$R] > $vPivot And IsNumber($avArray[$R])) Or (Not IsNumber($avArray[$R]) And StringCompare($avArray[$R], $vPivot) > 0) $R -= 1 WEnd Else While (StringCompare($avArray[$L], $vPivot) < 0) $L += 1 WEnd While (StringCompare($avArray[$R], $vPivot) > 0) $R -= 1 WEnd EndIf If $L <= $R Then $vTmp = $avArray[$L] $avArray[$L] = $avArray[$R] $avArray[$R] = $vTmp $L += 1 $R -= 1 EndIf Until $L > $R _RFLTA_QuickSort($avArray, $iStart, $R) _RFLTA_QuickSort($avArray, $L, $iEnd) EndFunc ;==>_RFLTA_QuickSort Func _RFLTA_ArrayConcatenate(ByRef $avArrayTarget, Const ByRef $avArraySource) Local $iUBoundTarget = UBound($avArrayTarget) - 1, $iUBoundSource = UBound($avArraySource) ReDim $avArrayTarget[$iUBoundTarget + $iUBoundSource] For $i = 1 To $iUBoundSource - 1 $avArrayTarget[$iUBoundTarget + $i] = $avArraySource[$i] Next EndFunc ;==>_RFLTA_ArrayConcatenate Func _RFLTA_Progress($vProgress = "", $sTotal = 0) $sCurrent_File = $sCurrent_File + 1 Return GUICtrlSetData($vProgress, $sCurrent_File * 100 / $sTotal) EndFunc ;==>_RFLTA_Progress Follow the $Break variable to understand what i've done (ofc if you want ), is there a good soluction (i've done it right?) or there is a better one? By the way im still working to make the detection of the total number file in a directory/drive faster, but with not luck Hi and thanks for this wonderful piece of code ! Edited March 7, 2012 by StungStang
Moderators Melba23 Posted March 8, 2012 Author Moderators Posted March 8, 2012 StungStang,Follow the $Break variable to understand what i've doneI did. is there a good soluction (i've done it right?) or there is a better one?I think you have very amply demonstrated why the idea of a progress bar for a deep recursive search is not a good idea - so at the very least you have done that right! Seriously, I really do think that you would do better using a marquee progress as I suggested earlier. M23 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
Recommended Posts