KickStarter15 Posted July 30, 2019 Share Posted July 30, 2019 😅 Hi Experts, Hope you have a good day!😊 I just wanna ask if this is possible to do in autoit. I want to search a folder name from a different drive and copy that folder to a specific path. Let say: My drive: D:/, C:/, Z:/, F:/ etc... One of these drives contains the folder that I want to find and copy it to my specified path including the subfolders and files inside that main folder. However, I could not find any related topic for multiple drive searching in this forum so I just wanna ask if this is possible, Experts. Also, if someone can direct me to a link if possible.😅 Thanks in advance, Experts.... Hope you can guide me on this. KS15 Programming is "To make it so simple that there are obviously no deficiencies" or "To make it so complicated that there are no obvious deficiencies" by C.A.R. Hoare. Link to comment Share on other sites More sharing options...
Deye Posted July 30, 2019 Share Posted July 30, 2019 (edited) if _FileListToArrayRec had a switch to return on the first instance found id say use that Else maybe something for you here : https://autoitscript.com/forum/topic/103846-recursive-folder-search-function/ cant be to hard to find something Deye Edited July 30, 2019 by Deye Link to comment Share on other sites More sharing options...
Nine Posted July 30, 2019 Share Posted July 30, 2019 You can use DriveGetDrive ($DT_ALL) to get all your drives. Then use _FileListToArrayRec with $FLTAR_FOLDERS and a mask of your searched folder in a loop for all drives you got. “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
Deye Posted July 30, 2019 Share Posted July 30, 2019 (edited) Found some spare time to test it out, Came up with this * Will list all root folders to an $aArray then recursively search each instance For faster returns the trick is to include as much of folders to ignore especially if they are going to be searched first (alphabetically) and happen to contain many files and folders .. #include <File.au3> $sSearchFolder = "SomeUniqueFolderName " $sStartDir = "D:\" $sSkip = "doc*;desk*" ;ignore named MsgBox(0, '', _SerchFolder($sStartDir, $sSearchFolder)) Func _SerchFolder($sStartDir, $sSearchFolder) Local $aArray = _FileListToArrayRec($sStartDir, "*|" & $sSkip, $FLTAR_FOLDERS, Default, Default, 2), $atmp For $i = 1 To UBound($aArray) - 1 $atmp = _FileListToArrayRec($aArray[$i], $sSearchFolder, $FLTAR_FOLDERS, $FLTAR_RECUR, Default, 2) If $atmp <> "" Then Return $atmp[1] Next EndFunc ;==>_SerchFolder Edit: just noticed that you are probably only looking for root folders .. Then what Nine suggested .. That And that my example wont do anything for the root folders Deye Edited July 30, 2019 by Deye FrancescoDiMuro 1 Link to comment Share on other sites More sharing options...
KickStarter15 Posted July 31, 2019 Author Share Posted July 31, 2019 (edited) 16 hours ago, Nine said: Then use _FileListToArrayRec with $FLTAR_FOLDERS @Nine, Thanks but as far as I know, _FileListToArrayRec will search the specified path from a drive right? In my case I don't have the specified path I need, I just want to search the folder from different drive randomly. Ok, so I did it this way using all your suggestion. Thanks! It searched the folder from where it was saved but the problem is I'm not declaring any path like I did in my sample code below. Is there any way to just input the folder name then search will happen from different drive?🤔 #include <File.au3> #include <MsgBoxConstants.au3> #include <AutoItConstants.au3> Example() Func Example() Local $aArray = DriveGetDrive($DT_ALL) For $i = 1 To $aArray[0] MsgBox($MB_SYSTEMMODAL, "", "Drive :" & @CRLF & StringUpper($aArray[$i])) Local $sDir = $aArray[$i] & "\Programs\RootFolder" ; The root folder is the folder that I need to search Local $aArrayFoldr = _FileListToArrayRec($sDir, "*", $FLTAR_FILESFOLDERS, $FLTAR_RECUR, $FLTAR_SORT) _ArrayDisplay($aArrayFoldr, "Sorted tree") Next EndFunc Edited July 31, 2019 by KickStarter15 Edited adding code. Programming is "To make it so simple that there are obviously no deficiencies" or "To make it so complicated that there are no obvious deficiencies" by C.A.R. Hoare. Link to comment Share on other sites More sharing options...
Nine Posted July 31, 2019 Share Posted July 31, 2019 @KickStarter15 At first I thought you were looking for a folder name "RootFolder"" anywhere in a any drives. Now I believe you want to search for a specific path "\Programs\RootFolder" in any drives. If I understand you correctly, maybe this : #include <Constants.au3> Global $sPath = "\Programs\RootFolder\" Example() Func Example() Local $aArray = DriveGetDrive($DT_ALL) For $i = 1 To $aArray[0] If FileExists ($aArray[$i] & $sPath) And StringInStr (FileGetAttrib ($aArray[$i] & $sPath), "D") Then ; check if exists and if it's a folder MsgBox ($MB_SYSTEMMODAL,"","Found") DirCopy ($aArray[$i] & $sPath, @ScriptDir & "\Temp") ExitLoop EndIf Next EndFunc ;==>Example “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
KickStarter15 Posted July 31, 2019 Author Share Posted July 31, 2019 1 hour ago, Nine said: At first I thought you were looking for a folder name "RootFolder"" anywhere in a any drives @Nine, Yes you're right, I'm looking for the folder name "RootFolder" anywhere in any drive and not the specific path.😄 Programming is "To make it so simple that there are obviously no deficiencies" or "To make it so complicated that there are no obvious deficiencies" by C.A.R. Hoare. Link to comment Share on other sites More sharing options...
KickStarter15 Posted July 31, 2019 Author Share Posted July 31, 2019 @Nine, I need to search the folder name and not the specified path. I have the below code found from this forum and it search the file which is similar on my concern. Maybe you can check on it and change it to folder name and not a file. #include <Array.au3> #include <File.au3> #include <AutoItConstants.au3> Global $aArray = DriveGetDrive($DT_ALL), $file = "FileName.txt" ; I don't need the filename but I need the folder name If @error Then MsgBox(0, "Error retrieving the drives", "Error : " & @error & ", Extended : " & @extended) Else For $i = 1 To $aArray[0] $aFileList = _FileListToArrayRec($aArray[$i] & "\", $file, $FLTAR_FILES, $FLTAR_RECUR, $FLTAR_NOSORT, $FLTAR_FULLPATH) If Not @error Then _ArrayDisplay($aFileList, "FileList for " & $aArray[$i]) EndIf Next EndIf Programming is "To make it so simple that there are obviously no deficiencies" or "To make it so complicated that there are no obvious deficiencies" by C.A.R. Hoare. Link to comment Share on other sites More sharing options...
Deye Posted July 31, 2019 Share Posted July 31, 2019 (edited) KickStarter15, Here is a fuller example for you to try : Spoiler #include <File.au3> MsgBox(262144, "", _Search("SomeFileOrFolderName", 2, "C:E", "doc*;desk*")) Func _Search($sSearch, $FLTAR_F = 2, $sSkipDrives = "", $sSkipRootFolders = "") ;$FLTAR_F = 1 for File ; 2 for folder Local $aDrives = DriveGetDrive($DT_FIXED), $aArray, $iIndex, $aTmp, $aSkipD If $sSkipDrives <> "" Then $aSkipD = StringSplit($sSkipDrives, ":") For $D = 1 To UBound($aSkipD) - 1 $iSkip = _ArraySearch($aDrives, $aSkipD[$D] & ":") If Not @error Then _ArrayDelete($aDrives, $iSkip) Next EndIf For $D = 1 To UBound($aDrives) - 1 $aArray = _FileListToArrayRec($aDrives[$D] & "\", "*|" & $sSkipRootFolders, 0, Default, Default, 2) $iIndex = _ArraySearch($aArray, "\" & $sSearch & ($FLTAR_F = 1 ? "" : "\"), 0, 0, 0, 1) If Not @error Then Return $aArray[$iIndex] For $i = 1 To UBound($aArray) - 1 $aTmp = _FileListToArrayRec($aArray[$i], $sSearch, ($FLTAR_F = 1 ? 1 : 2), $FLTAR_RECUR, Default, 2) If $aTmp <> "" Then Return $aTmp[1] Next Next Return "" EndFunc ;==>_Search Deye Edited July 31, 2019 by Deye Link to comment Share on other sites More sharing options...
Nine Posted July 31, 2019 Share Posted July 31, 2019 4 hours ago, KickStarter15 said: Maybe you can check on it and change it to folder name and not a file. #include <Constants.au3> #include <File.au3> Const $sFolder = "Applications" Local $aDrives = DriveGetDrive($DT_ALL) If @error Then Exit MsgBox ($MB_SYSTEMMODAL,"","Unable to get drives") Local $aFolder, $aListFolders[0] For $i = 1 To $aDrives[0] $aFolder = _FileListToArrayRec (StringUpper($aDrives[$i]) & "\", $sFolder, $FLTAR_FOLDERS, $FLTAR_RECUR, $FLTAR_SORT, $FLTAR_FULLPATH) If @error Then ContinueLoop _ArrayDelete ($aFolder, 0) _ArrayAdd ($aListFolders, $aFolder) Next _ArrayDisplay ($aListFolders) Here for a full list of all occurrences of a specific folder anywhere on any drives. “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
KickStarter15 Posted August 1, 2019 Author Share Posted August 1, 2019 @Deye, Thanks for the example you've gave, however, it's not showing the folder that I need to search it only shows the blank mssgbox.😊 @Nine, Yup it's working perfectly but it took too long in searching the folder, so I tried declaring the drive individually and the searching is fast. Which gives me the idea to have a drop down to individualized the drive on where to search👍. What do you think?😅 Programming is "To make it so simple that there are obviously no deficiencies" or "To make it so complicated that there are no obvious deficiencies" by C.A.R. Hoare. Link to comment Share on other sites More sharing options...
Deye Posted August 1, 2019 Share Posted August 1, 2019 maybe the switches are confusing to you what if you tried it with the minimal like so: MsgBox(262144, "", _Search("FolderName", 2)) Link to comment Share on other sites More sharing options...
KickStarter15 Posted August 1, 2019 Author Share Posted August 1, 2019 (edited) @Deye, Thanks, it is now showing the folder as expected but same with @Nine's provide code, it took long time to get the result of the searched folder. If anyhow you can suggest on my Idea to create a dropdown and can search faster. @Nine and @Deye, Here's my sample so far.😄 Maybe you can make the searching faster than the regular searching.😅 expandcollapse popup#include <GUIConstantsEx.au3> #include <Constants.au3> #include <File.au3> #include <Array.au3> $aArray = DriveGetDrive("ALL") $sString = _ArrayToString($aArray, "|", 1) $hGUI = GUICreate("Test", 310, 50) $hCombo = GUICtrlCreateCombo("", 10, 10, 200, 20) GUICtrlSetData(-1, $sString) $Button = GUICtrlCreateButton("Search", 215, 08, 85, 25) GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $Button DriveSearch() EndSwitch WEnd Func DriveSearch() Const $sFolder = "RootFolder" Local $aDrives = GUICtrlRead($hCombo) If @error Then Exit MsgBox ($MB_SYSTEMMODAL,"","Unable to get drives") Local $aFolder, $aListFolders[0] ; For $i = 1 To $aDrives[0] ; MsgBox(0,"",$aDrives[$i]) $aFolder = _FileListToArrayRec (StringUpper($aDrives) & "\", $sFolder, $FLTAR_FOLDERS, $FLTAR_RECUR, $FLTAR_SORT, $FLTAR_FULLPATH) ; If @error Then ContinueLoop _ArrayDelete ($aFolder, 0) _ArrayAdd ($aListFolders, $aFolder) ; Next _ArrayDisplay ($aListFolders) EndFunc Edited August 1, 2019 by KickStarter15 Programming is "To make it so simple that there are obviously no deficiencies" or "To make it so complicated that there are no obvious deficiencies" by C.A.R. Hoare. Link to comment Share on other sites More sharing options...
Deye Posted August 1, 2019 Share Posted August 1, 2019 KickStarter15, Finish the gui part nicely with an edit search box included etc .. and tell me when its ready or better yet post it, By then then i will combine something that will find your searches in an instant And Yes you will have to believe me on this. Deal ? FrancescoDiMuro and KickStarter15 2 Link to comment Share on other sites More sharing options...
KickStarter15 Posted August 1, 2019 Author Share Posted August 1, 2019 (edited) @Deye, Here's what my initial GUI looks like. Later on buttons and others will be added depending on my heads request. 😅 Partially here it is: expandcollapse popup#include <GUIConstantsEx.au3> #include <Constants.au3> #include <File.au3> #include <Array.au3> $aArray = DriveGetDrive("ALL") $sString = _ArrayToString($aArray, "|", 1) $hGUI = GUICreate("Test", 310, 300) $hCombo = GUICtrlCreateCombo("", 10, 10, 200, 20) GUICtrlSetData(-1, $sString) $input = GUICtrlCreateInput("", 210, 35, 90, 20) $label1 = GUICtrlCreateLabel("Folder/File: ", 150, 38, 53, 20) $Folder = GUICtrlCreateRadio("Folder", 10, 32, 60, 25) GUICtrlSetState($Folder, $GUI_ENABLE) $File = GUICtrlCreateRadio("File", 80, 32, 35, 25) GUICtrlSetState($Folder, $GUI_ENABLE) $Button = GUICtrlCreateButton("Search", 215, 08, 85, 25) $Progress = GUICtrlCreateProgress(10, 60, 290, 20) ; progress bar to show the progress while searching $label = GUICtrlCreateLabel("Progress search folder here ie. D:\Folder1\Folder2\...", 10, 82, 350, 20) $ListView1 = GUICtrlCreateListView("Count|Path", 10, 100, 290, 190) ; generates the searched results... GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $Button If GUICtrlRead($Folder) = $GUI_CHECKED Then MsgBox(0,"","Checking") GUICtrlSetState($File, $GUI_DISABLE) DriveSearch() EndIf If GUICtrlRead($File) = $GUI_CHECKED Then MsgBox(0,"","Checking 1") GUICtrlSetState($Folder, $GUI_DISABLE) Call("_Search") ; Won't run. How? EndIf EndSwitch WEnd Func DriveSearch() Const $sFolder = GUICtrlRead($input) Local $aDrives = GUICtrlRead($hCombo) MsgBox(0,"",$aDrives) If @error Then Exit MsgBox ($MB_SYSTEMMODAL,"","Unable to get drives") Local $aFolder, $aListFolders[0] $aFolder = _FileListToArrayRec (StringUpper($aDrives) & "\", $sFolder, $FLTAR_FOLDERS, $FLTAR_RECUR, $FLTAR_SORT, $FLTAR_FULLPATH) GUICtrlSetData($label, $aListFolders) ; I want to show the folder being searched from this label _ArrayDelete ($aFolder, 0) _ArrayAdd ($aListFolders, $aFolder) _ArrayDisplay ($aListFolders) ; replace this with $ListView1 GUICtrlSetData($ListView1, _ArrayAdd ($aListFolders, $aFolder)) ; to show searched folder/s in this field. GUICtrlSetState($File, $GUI_ENABLE) EndFunc MsgBox(262144, "", _Search(GUICtrlRead($input), 1)) ; configure to find file Func _Search($sSearch, $FLTAR_F = 1, $sSkipDrives = "", $sSkipRootFolders = "") ;$FLTAR_F = 1 for File ; 2 for folder MsgBox(0,"","Testing") Local $aDrives = GUICtrlRead($hCombo), $aArray, $iIndex, $aTmp, $aSkipD If $sSkipDrives <> "" Then $aSkipD = StringSplit($sSkipDrives, ":") For $D = 1 To UBound($aSkipD) - 1 $iSkip = _ArraySearch($aDrives, $aSkipD[$D] & ":") If Not @error Then _ArrayDelete($aDrives, $iSkip) Next EndIf For $D = 1 To UBound($aDrives) - 1 $aArray = _FileListToArrayRec($aDrives[$D] & "\", "*|" & $sSkipRootFolders, 0, Default, Default, 2) $iIndex = _ArraySearch($aArray, "\" & $sSearch & ($FLTAR_F = 1 ? "" : "\"), 0, 0, 0, 1) If Not @error Then Return $aArray[$iIndex] For $i = 1 To UBound($aArray) - 1 $aTmp = _FileListToArrayRec($aArray[$i], $sSearch, ($FLTAR_F = 1 ? 1 : 2), $FLTAR_RECUR, Default, 2) If $aTmp <> "" Then Return $aTmp[1] Next Next Return "" GUICtrlSetState($Folder, $GUI_ENABLE) EndFunc Edited August 1, 2019 by KickStarter15 Code updated Programming is "To make it so simple that there are obviously no deficiencies" or "To make it so complicated that there are no obvious deficiencies" by C.A.R. Hoare. Link to comment Share on other sites More sharing options...
Deye Posted August 1, 2019 Share Posted August 1, 2019 (edited) KickStarter15, So Good you got the gui updated a little bit more by now, I'm Not going to dwell into it , Its all yours to finish but now for my part of the deal : This gem function is thanks to mister Yashied! To try: First choose a drive and continue typing your search, the string of the drive & search will be used as parameters you can use wild card searches for example File*.mp3 Newer Code available from this link expandcollapse popup#include <File.au3> #include <String.au3> #include <GUIConstantsEx.au3> $aArray = DriveGetDrive("ALL") For $i = 1 To $aArray[0] $aArray[$i] = StringUpper($aArray[$i]) Next $sString = _ArrayToString($aArray, "|", 1) $hGUI = GUICreate("Test", 310, 100) ;Use it like this for this example $hCombo = GUICtrlCreateCombo("D:FileFolder", 10, 10, 200, 20) ;File*.mp3 GUICtrlSetFont(-1, 12) GUICtrlSetData(-1, $sString) $Button = GUICtrlCreateButton("Search", 215, 08, 85, 25) GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $Button MsgBox(262144, "", _Search(GUICtrlRead($hCombo), Default, 7)) EndSwitch WEnd Func _Search($sSearch, $iStartLevel = 1, $iEndLevel = 7) ; $iLevel folders levels deeep Local $a = StringSplit($sSearch, ":"), $Ret = _GetAppropriatePath($a[1] & ":\*" & $a[2] & "*") If $Ret Then Return $Ret For $i = $iStartLevel To $iEndLevel $Ret = _GetAppropriatePath($a[1] & ":\*" & _StringRepeat("\*", $i) & $a[2] & "*") If $Ret Then Return $Ret Next Return "" EndFunc ;==>_Search Func _GetAppropriatePath($sPath, $iLevel = 0) Local $hSearch, $tPath, $File, $Item, $Path, $Ret, $Dir = '', $Suf = '', $Result = '' $tPath = DllStructCreate('wchar[1024]') $Ret = DllCall('kernel32.dll', 'dword', 'GetFullPathNameW', 'wstr', $sPath, 'dword', 1024, 'ptr', DllStructGetPtr($tPath), 'ptr', 0) If (@error) Or (Not $Ret[0]) Then Return '' EndIf $sPath = DllStructGetData($tPath, 1) If StringRight($sPath, 1) = '\' Then $Dir = '\' EndIf $Item = StringSplit(StringRegExpReplace($sPath, '\\\Z', ''), '\') Select Case $iLevel + 1 = $Item[0] If FileExists($sPath) Then Return $sPath Else Return '' EndIf Case $iLevel + 1 > $Item[0] Return '' EndSelect For $i = 1 To $iLevel + 1 $Result &= $Item[$i] & '\' Next $Result = StringRegExpReplace($Result, '\\\Z', '') If Not FileExists($Result) Then Return '' EndIf $hSearch = FileFindFirstFile($Result & '\*') If $hSearch = -1 Then Return '' EndIf For $i = $iLevel + 3 To $Item[0] $Suf &= '\' & $Item[$i] Next While 1 $File = FileFindNextFile($hSearch) If @error Then $Result = '' ExitLoop EndIf If (Not @extended) And ($Dir) And ($iLevel + 2 = $Item[0]) Then ContinueLoop EndIf $Ret = DllCall('shlwapi.dll', 'int', 'PathMatchSpecW', 'wstr', $File, 'wstr', $Item[$iLevel + 2]) If (Not @error) And ($Ret[0]) Then $Path = _GetAppropriatePath($Result & '\' & $File & $Suf & $Dir, $iLevel + 1) If $Path Then $Result = $Path ExitLoop EndIf EndIf WEnd FileClose($hSearch) Return $Result EndFunc Deye Edited August 1, 2019 by Deye Added $iStartLevel .. Link to comment Share on other sites More sharing options...
KickStarter15 Posted August 2, 2019 Author Share Posted August 2, 2019 @Deye, Thanks and it's working and it's faster now. However, it stop searching when the code found 1 match but in fact, there are more than 1 of the searched folder was saved from that drive. Programming is "To make it so simple that there are obviously no deficiencies" or "To make it so complicated that there are no obvious deficiencies" by C.A.R. Hoare. Link to comment Share on other sites More sharing options...
Deye Posted August 2, 2019 Share Posted August 2, 2019 (edited) KickStarter15, See if this gets you other folders, the changes I made are not fully thought through but seemed to work well @making it work for you hopefully Works but still a little slower than _FileListToArrayRec used with the depth option see next post Spoiler expandcollapse popup#include <File.au3> #include <String.au3> #include <GUIConstantsEx.au3> $aArray = DriveGetDrive("ALL") For $i = 1 To $aArray[0] $aArray[$i] = StringUpper($aArray[$i]) Next $sString = _ArrayToString($aArray, "|", 1) $hGUI = GUICreate("Test", 320, 125) $hCombo = GUICtrlCreateCombo("", 10, 8, 180, 20) ;File*.mp3 GUICtrlSetFont(-1, 12) GUICtrlSetData(-1, $sString) $hCombo2 = GUICtrlCreateCombo("LevelFiveDefault", 10, 70, 180, 20) ;File*.mp3 GUICtrlSetFont(-1, 12) GUICtrlSetData(-1, "1|2|3|4|5|6|7") $Button = GUICtrlCreateButton("Search", 215, 08, 100, 25) GUICtrlSetFont(-1, 12) $ButtonCancel = GUICtrlCreateButton("Abort Search", 215, 45, 100, 25) $ButtonResult = GUICtrlCreateButton("Copy result", 215, 80, 100, 25) GUICtrlSetFont(-1, 12) $File = GUICtrlCreateRadio("File", 10, 38, 70, 25) GUICtrlSetFont(-1, 12) GUICtrlSetState(-1, $GUI_CHECKED) $Folder = GUICtrlCreateRadio("Folder", 100, 38, 70, 25) GUICtrlSetFont(-1, 12) $iCountTotal = 500 Global $aResult, $sFilePath = @ScriptDir & "\TestUniqueResults1.txt", $bCancel = False HotKeySet("{ESC}", "TerminateSearch") GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $Button $iLevel = GUICtrlRead($hCombo2) $bFile = BitAND(GUICtrlRead($File), $GUI_CHECKED) ? 1 : 0 _Run(GUICtrlRead($hCombo), StringIsAlpha($iLevel) = 1 ? 5 : $iLevel, $bFile) Case $ButtonCancel $bCancel = True Case $ButtonResult _FileWriteFromArray($sFilePath, $aResult, 1) EndSwitch WEnd Func _Run($sSearchTerm, $iEndLevel, $bFile = 0) $bCancel = False ConsoleWrite("Level = " & $iEndLevel & @LF) Local $hTimer = TimerInit() $aResult = _Search($sSearchTerm, $iEndLevel, $bFile) ConsoleWrite(TimerDiff($hTimer) & @LF) _ArrayDisplay($aResult, "Level " & $iEndLevel) ConsoleWrite("Done Searching" & @LF & @LF) EndFunc ;==>_Run Func _Search($sSearch, $iEndLevel = 5, $bFile = 1) Local $a = StringSplit($sSearch, ":"), $sPath, $aRet[500], $iCount = 1 $sPattern = "(?i)^" & StringReplace(StringRegExpReplace($a[2], "[][$^.{}()+\-]", "\\$0"), "*", ".*?") & "$" $sPath = $a[1] & ":" & _StringRepeat("\*", $iEndLevel + 1) $sPath = StringTrimRight($sPath, 1) & $a[2] _GetArray($aRet, $iCount, $bFile, $a[2], $sPattern, $sPath) Local $iIndex = _ArraySearch($aRet, "", 1) Local $a = _ArrayExtract($aRet, 0, (@error = -1 ? UBound($aRet) : $iIndex - 1)) _ArraySort($a) $a[0] = UBound($a) - 1 Return $a EndFunc ;==>_Search Func _GetArray(ByRef $array, ByRef $iCount, $bFile, $filter, $sPattern, $sPath, $iLevel = 0) Local $Item = StringSplit(StringRegExpReplace($sPath, '\\\Z', ''), '\') If $iLevel + 1 >= $Item[0] Then Return Local $hSearch, $File, $Suf, $Result, $isFolder For $i = 1 To $iLevel + 1 $Result &= $Item[$i] & '\' Next $Result = StringRegExpReplace($Result, '\\\Z', '') $isFolder = StringInStr(FileGetAttrib($Result), "D") $hSearch = FileFindFirstFile($Result & '\*') If $iCount >= $iCountTotal Then $iCountTotal += 500 ReDim $array[$iCountTotal] EndIf If StringRegExp($Item[$iLevel + 1], $sPattern) Then If $isFolder And Not $bFile Then $array[$iCount] = $Result $iCount += 1 ElseIf Not $isFolder And $bFile Then $array[$iCount] = $Result $iCount += 1 EndIf EndIf If $hSearch = -1 Then Return EndIf For $i = $iLevel + 3 To $Item[0] $Suf &= '\' & $Item[$i] Next While 1 $File = FileFindNextFile($hSearch) If @error Then ExitLoop If (Not @extended) And ($iLevel + 2 = $Item[0]) Then ContinueLoop EndIf _GetArray($array, $iCount, $bFile, $filter, $sPattern, $Result & '\' & $File & $Suf & "\", $iLevel + 1) If $bCancel Then Return WEnd FileClose($hSearch) EndFunc ;==>_GetArray Func TerminateSearch() $bCancel = True EndFunc ;==>TerminateSearch Deye Edited August 6, 2019 by Deye Cosmetic & Fixed Link to comment Share on other sites More sharing options...
Network_Guy Posted August 2, 2019 Share Posted August 2, 2019 (edited) you can try my MultiTasking.au3 to execute a function (drivesearch,_search , etc ) in parallel ,and if you are interested to create a GUI script ,you can use this UDF also to do search without effecting (Hanging) the GUI. Note :- (you need to download Multi-Tasking ,MailSlot UDF), in your case try this code (without GUI):- expandcollapse popup#include <array.au3> #include <file.au3> #include <FileConstants.au3> #include <MultiTasking.au3> $timer = TimerInit() ; Calcuate total execution time from here _Task_SetVar("ResultString", "") ;Create string variable all Tasks can Read & Write to it $Drives = DriveGetDrive("All") ;get all drives on your PC Local $TaskArray[0] ; create PID array for all created Tasks For $i = 1 To $Drives[0] If DriveStatus($Drives[$i]) = "READY" Then ; Scan usable drives only (Ignore empty CD , unformated partion , etc ......) $TaskID = _Task_Create("", "SearchDrive", $Drives[$i]) ; parallel execute searchdrive function with 1 parmeter ( driveletter from $drives array) _ArrayAdd($TaskArray, $TaskID) ; add current Task PID to all Tasks PID array EndIf Next _Task_Join($TaskArray) ; wait for all parallel tasks to complete ; $temp = _Task_GetVar("ResultString") ; get result as big string $temp = StringTrimRight($temp, 1) ; remove last "|" char $ResultArray = StringSplit($temp, "|", 2) ; convert string to array $totaltime = TimerDiff($timer) ; calculate total exec time _ArrayDisplay($ResultArray) ;show result MsgBox(0, "", $totaltime) ; show total exec time Func SearchDrive($drive) $Searchlocation = $drive ; drive to be searched $SearchFor = "RootFolder" ; folder name ;~ $SearchLvlDepth=1 ; 1 lvl Depth ;~ $SearchLvlDepth=2 ; 2 lvl Depth so on $SearchLvlDepth = -1 ; Search in all subfolders (unlimited recursion) $array = _FileListToArrayRec($Searchlocation, $SearchFor, $FLTAR_FOLDERS, -1 * $SearchLvlDepth, $FLTAR_NOSORT, $FLTAR_FULLPATH) If $array <> "" Then _ArrayDelete($array, 0) $Result = _ArrayToString($array) ; convert result array to string _Task_SetVarEx("ResultString", "&=", $Result & "|") ; safe append current result to ResultString (all tasks can read &write to Resultstring) EndIf EndFunc ;==>SearchDrive Edited August 2, 2019 by Network_Guy Link to comment Share on other sites More sharing options...
Deye Posted August 2, 2019 Share Posted August 2, 2019 (edited) @Network_Guy, Dealing with this one was enough for me for today will have to look at your example and have a think on it, later on .. Anyways to all and KickStarter15, just made it all work (In my post above this one) , added radios for file \ folder searches .. Deye Edit: spoke to soon about making it all work, Still a small issue between level 1 and the rest of levels Edit : Fixed A little faster solution brought with the advice of @BrewManNH Edited August 5, 2019 by Deye 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