Deye Posted August 1, 2019 Share Posted August 1, 2019 (edited) derived from here I have updated the example to search file\folders in levels from root folders = 1 for the example search for a specific folder that you know exists in level 2 but wont exist in the following levels if the end level is 7 .. I have added a button to abort the search otherwise the gui will hang without being able to gracefully exit Usage: select a drive from the drop-down combo and type some folder name right after the selected drive just interested to make it quit searching on demand if anyone can spot how it may be done or any other ideas Spoiler expandcollapse popup#include <File.au3> #include <String.au3> #include <GUIConstantsEx.au3> HotKeySet("{ESC}", "TerminateSearch") $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("", 10, 10, 200, 20) ;File*.mp3 GUICtrlSetFont(-1, 12) GUICtrlSetData(-1, $sString) $hCombo2 = GUICtrlCreateCombo("Start Level", 10, 50, 120, 20) ;File*.mp3 GUICtrlSetFont(-1, 12) GUICtrlSetData(-1, "1|2|3|4|5|6|7") $Button = GUICtrlCreateButton("Search", 215, 08, 85, 25) $ButtonCancel = GUICtrlCreateButton("Abort Search", 215, 38, 85, 25) $ButtonResult = GUICtrlCreateButton("Copy result", 215, 68, 85, 25) $Result = "" $Cancel = False GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $Button $sSearch = GUICtrlRead($hCombo) $iLevel = GUICtrlRead($hCombo2) If StringIsAlpha($iLevel) Then $iLevel = 1 $Result = _Search($sSearch, $iLevel) MsgBox(262144, "", $Result) Case $ButtonCancel $Cancel = True Case $ButtonResult ClipPut($Result) EndSwitch Sleep(10) WEnd Func _Search($sSearch, $iStartLevel = 1, $iEndLevel = 7) ; $iLevel folders levels deeep Local $a = StringSplit($sSearch, ":"), $Ret Switch $iStartLevel Case 1 $Ret = _GetAppropriatePath($a[1] & ":\*" & $a[2] & "*") If $Ret Then Return $Ret $iStartLevel += 1 ContinueCase Case Else While $Cancel = False For $i = $iStartLevel - 1 To $iEndLevel $Ret = _GetAppropriatePath($a[1] & ":\*" & _StringRepeat("\*", $i) & $a[2] & "*") If $Ret Then Return $Ret Next WEnd $Cancel = False EndSwitch 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 $Cancel = False $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) $Cancel = False Return $Result EndFunc ;==>_GetAppropriatePath Func TerminateSearch() $Cancel = True EndFunc ;==>TerminateSearch Thanks Edit: works ok with a hotkeyset @setting $cancel to True but not from the button in the loop . will have to do for now : Updated Code to terminate a search with the "ESC" key Edited August 1, 2019 by Deye Link to comment Share on other sites More sharing options...
BrewManNH Posted August 2, 2019 Share Posted August 2, 2019 Why not just use FileListToArrayRec with a depth parameter set? Deye 1 If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
Deye Posted August 2, 2019 Author Share Posted August 2, 2019 BrewManNH, Didn't notice that option before Will try that soon .. Thanks Deye Link to comment Share on other sites More sharing options...
Deye Posted August 3, 2019 Author Share Posted August 3, 2019 (edited) Absolutely @BrewManNH I struggled a bit to make it work in the way you suggested but it finally clinged 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) $Folder = GUICtrlCreateRadio("Folder", 100, 38, 70, 25) GUICtrlSetFont(-1, 12) GUICtrlSetState(-1, $GUI_CHECKED) $Cancel = False ;~ HotKeySet("{ESC}", "TerminateSearch") GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $Button $sSearch = GUICtrlRead($hCombo) $iLevel = GUICtrlRead($hCombo2) If StringIsAlpha($iLevel) Then $iLevel = 5 $aResult = _Search($sSearch, BitAND(GUICtrlRead($File), $GUI_CHECKED) ? 0 : 1, $iLevel) _ArrayDisplay($aResult, "Level " & $iLevel) ConsoleWrite("Done Searching" & @LF & @LF) Case $ButtonCancel $Cancel = True Case $ButtonResult ClipPut(_ArrayToString($aResult, @LF)) EndSwitch Sleep(10) WEnd Func _Search($sSearch, $bFolder = 1, $iEndLevel = 5) Local $a = StringSplit($sSearch, ":"), $aRet[0] ConsoleWrite("Level = " & $iEndLevel & @LF) Return _FileListToArrayRec($a[1] & ":\", "*" & $a[2] & "*", ($bFolder ? 2 : 1), ($iEndLevel - 1) * -1, Default, 2) EndFunc ;==>_Search Deye Edited August 3, 2019 by Deye cleanup 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