Xajar Posted May 31, 2007 Share Posted May 31, 2007 I'm having some problems with a script I made to collect all the files and sub folders within a folder. When I use _Singleton to allow only one occurrence, the arguments pass but the first occurrence doesn't wait for the other occurrences to finish the recursive file search. I want to pause the script till the list of files is finished being gathered before enabling controls. Any help would be appreciated. Here is the code in question and another script to add/remove support for right-clicking on folders. Build List.au3 expandcollapse popup#include <GUIConstants.au3> #include <GuiList.au3> #include <Misc.au3> ;~ Passes the command line arguments to the first occurrence If _Singleton( 'Build List',1 ) = 0 Then If $CmdLineRaw <> '' Then If IsFolder( $CmdLineRaw ) Then ScanFolders( $CmdLineRaw ) Else ControlCommand( 'AForm1','','ListBox1','AddString', FileGetLongName($CmdLineRaw) ) EndIf EndIf Exit EndIf ;~ Creates the GUI $Form1 = GUICreate("AForm1", 633, 233, 193, 115) $List1 = GUICtrlCreateList("", 8, 8, 617, 188) $Button1 = GUICtrlCreateButton("AButton1", 8, 200, 81, 25, 0) GUICtrlSetState( -1,$GUI_DISABLE ) GUISetState(@SW_SHOW) ;~ Parses the command line arguments For $i = 1 To $CmdLine[0] If IsFolder( $CmdLine[$i] ) Then ScanFolders( $CmdLine[$i] ) Else ControlCommand( 'AForm1','','ListBox1','AddString', FileGetLongName($CmdLine[$i]) ) EndIf Next ;~ I need the script to wait for the list to finish MsgBox( '','Here is the problem',"I don't want to see this untill all the occurrences have passed their arguments and the file list is complete..." ) GUICtrlSetState( $Button1,$GUI_ENABLE ) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd ;~ Gathers the folders/files and stores them in the listbox Func ScanFolders( $Path ) local $fileHandle, $file, $dirHandle, $dir local const $FILESPEC = "*.*" $fileHandle = fileFindFirstFile( $path & "\" & $FILESPEC ) If $fileHandle <> -1 Then while ( 1 ) $file = fileFindNextFile( $fileHandle ) If @error = 1 Then exitLoop If $file = "." or $file = ".." Then continueLoop $file = $path & "\" & $file If isFolder( $file ) Then continueLoop ControlCommand( 'AForm1','','ListBox1','AddString', FileGetLongName($file) ) wEnd fileClose( $fileHandle ) EndIf $dirHandle = fileFindFirstFile( $path & "\*.*" ) If $dirHandle <> -1 Then while ( 1 ) $dir = fileFindNextFile( $dirHandle ) If @error = 1 Then exitLoop If $dir = "." or $dir = ".." Then continueLoop $dir = $path & "\" & $dir If not( IsFolder($dir) ) Then continueLoop ScanFolders( $dir ) wEnd fileClose( $dirHandle ) EndIf EndFunc ;~ Checks if a path is a folder or file Func IsFolder( $Path ) If stringInStr( fileGetAttrib($Path), "D" ) Then Return 1 Return 0 EndFunc Add Right Click Support.au3 #include <GUIConstants.au3> #Region ### START Koda GUI section ### Form=C:\Documents and Settings\Xajar\Desktop\RSA Encryption\xCrypter_Setup.kxf $Form1 = GUICreate("Right-Click Setup", 186, 50, 193, 115) $Label2 = GUICtrlCreateLabel("Right-Click On Folder Option", 8, 8, 138, 17) $btn_add_folder = GUICtrlCreateButton("Add", 8, 25, 81, 21, 0) $btn_remove_folder = GUICtrlCreateButton("Remove", 96, 25, 81, 21, 0) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### While 1 $Msg = GUIGetMsg() Switch $Msg Case $GUI_EVENT_CLOSE Exit Case $btn_add_folder RegWrite("HKEY_CLASSES_ROOT\Folder\shell\Build List...\Command", "", "REG_SZ", @ScriptDir & '\build list.exe %1') Case $btn_remove_folder RegDelete ( "HKEY_CLASSES_ROOT\Folder\shell\Build List..." ) EndSwitch WEnd Link to comment Share on other sites More sharing options...
PsaltyDS Posted May 31, 2007 Share Posted May 31, 2007 (edited) Recursion should not require calling a script in a new process over and over. That is really going to be slow and eat resources. Recursion should be done by a function calling itself. Here is one of many examples on this forum. This one happens to have been written by a particularly good looking flightless water fowl... P.S. On closer examination, you already have your ScanFolders() function calling itself for recursion, so what are the conditions calling the script repeatedly? Edited May 31, 2007 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
Xajar Posted May 31, 2007 Author Share Posted May 31, 2007 The problem with the above code I posted was when I tried to highlight multiple folders to be passed into a sub folder/file search through a right click on folders/files. Once the first occurrence finished searching the controls become enabled while the other occurrences were still adding files to the file list being built. Link to comment Share on other sites More sharing options...
PsaltyDS Posted May 31, 2007 Share Posted May 31, 2007 The problem with the above code I posted was when I tried to highlight multiple folders to be passed into a sub folder/file search through a right click on folders/files. Once the first occurrence finished searching the controls become enabled while the other occurrences were still adding files to the file list being built.I get it now. You are creating a right-click context for folders called "Build List...". If you have more than one object selected when you use it, it kicks off one instance for each object, but you want them all to aggregate the results. I would use _Singleton() at the very top of the script. If this is the only instance, then this instance becomes master and is responsible for creating the aggregation GUI.Later instances of the same script would see that they are not the master because of _Singleton(), and would know to only update the master GUI, not create one themselves. The master instance will know it's done when _Singleton() is run again and indicates it is the only instance left. So all the master has to do is create the GUI update it from its own command line arguments, then after a minimal time delay wait for it to be the only one left. All the late-comer instances have to do is update the master's GUI and exit.Make sense? Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
Xajar Posted June 1, 2007 Author Share Posted June 1, 2007 Thanks, I was able to get it. This is what I came up with. expandcollapse popup#NoTrayIcon #include <GUIConstants.au3> #include <GuiList.au3> #include <Misc.au3> #include <Array.au3> #include <File.au3> Global $Wait = False Global $Title = 'AForm1' ;~ Passes the command line arguments to the first occurrence If _Singleton( 'Build List',1 ) = 0 Then;Second occurrence If $CmdLineRaw <> '' Then $Wait = True DisableControls() If IsFolder( $CmdLineRaw ) Then ScanFolders( $CmdLineRaw ) Else ControlCommand( $Title,'','ListBox1','AddString', FileGetLongName($CmdLineRaw) ) EndIf $Wait = False SetTimeOut() EndIf Exit Else;First occurrence ;~ Creates the GUI $Form1 = GUICreate("AForm1", 633, 233, 193, 115) $List1 = GUICtrlCreateList("", 8, 8, 617, 188) $Button1 = GUICtrlCreateButton("AButton1", 8, 200, 81, 25, 0) GUICtrlSetState( -1,$GUI_DISABLE ) GUISetState(@SW_SHOW) ;~ Parses the command line arguments For $i = 1 To $CmdLine[0] If IsFolder( $CmdLine[$i] ) Then ScanFolders( $CmdLine[$i] ) Else ControlCommand( $Title,'','ListBox1','AddString', FileGetLongName($CmdLine[$i]) ) EndIf Next EndIf EnableControls() While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Func SetTimeOut() If $Wait = False Then Sleep( 10000 ) EnableControls() EndIf EndFunc Func EnableControls() If $Wait = False Then ControlEnable( 'AForm1','','Button1' ) EndIf EndFunc Func DisableControls() ControlDisable( 'AForm1','','Button1' ) EndFunc ;~ Checks if a path is a folder or file Func IsFolder( $Path ) If stringInStr( fileGetAttrib($Path), "D" ) Then Return 1 Return 0 EndFunc Func ScanFolders($Path) local $fileHandle, $file, $dirHandle, $dir local const $FILESPEC = "*.*" $fileHandle = fileFindFirstFile( $path & "\" & $FILESPEC ) If $fileHandle <> -1 Then while ( 1 ) $file = fileFindNextFile( $fileHandle ) If @error = 1 Then exitLoop If $file = "." or $file = ".." Then continueLoop $file = $path & "\" & $file If isFolder( $file ) Then continueLoop ControlCommand( $Title,'','ListBox1','AddString', FileGetLongName($file) ) wEnd fileClose( $fileHandle ) EndIf $dirHandle = fileFindFirstFile( $path & "\*.*" ) If $dirHandle <> -1 Then while ( 1 ) $dir = fileFindNextFile( $dirHandle ) If @error = 1 Then exitLoop If $dir = "." or $dir = ".." Then continueLoop $dir = $path & "\" & $dir If not( IsFolder($dir) ) Then continueLoop ScanFolders( $dir ) wEnd fileClose( $dirHandle ) EndIf EndFunc 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