Sign in to follow this  
Followers 0
erik7426

FileListToArray Help

10 posts in this topic

I need help using _FileListToArray or some variation of it.

Here is what I am trying to do.

I need to locate files with a specific extension (.exe.CAB) on a drive regardless of what subfolder they are in. The FileListToArray function doesn't allow for recursion or multiple search paths. So, after searching the forum I found several functions and have tried all of them(_FileListToArrayNT, _FileListToArrayEx3 and _FileListToArrayXT)

They work partially. For example if I search C:\ and there are files that match the criteria in C:\Windows and C:\Windows\system32 the functions will only find the file in C:\Windows. Maybe it's something I'm doing wrong...

Below is an example of one of my attempts

#Include <File.au3>
#Include <Array.au3>

$testDrive = "K:\"

;First array to identify all of my folders on the root of K drive
$myFolders = _FileListToArray($testDrive,"*",2)

$myPath = ""

For $Fldr = 1 to $myFolders[0]
    $myPath = $myPath & $testDrive & $myFolders[$Fldr] & ";"
Next




;Testing parameters
Dim $Repeat = 1
Dim $SearchPath = $myPath
Dim $Pattern = "*.exe.CAB"
Dim $SrchType = 1; What to search for: 0 = Files and Folders, 1 = Files Only, 2 = Folders Only
Dim $PathType = 2; Format of returned string: 0 = file/folder name only, 1 = partial/referential path, 2 = full path
Dim $Exclude = ""
Dim $Recursiv = True

  $aRet = _FileListToArrayEx3($SearchPath, $Pattern, $SrchType, $PathType, $Recursiv, $Exclude, 1)
  _ArrayDisplay($aRet)
Exit

; #FUNCTION# ===========================================================================================
; Name:          _FileListToArrayEx3
; Description:    full compatible _FileListToArray replacement  (with more speed and additional features)
;                  additional: multi-path, multi-filter, multi exclude-filter, recursiv search
;                  optional full pathname
; Syntax:          _FileListToArrayEx3([$sPath = @ScriptDir, [$sFilter = "*", [$iSrchType, [$bRecursiv = False, [$sExclude = "", [$iFormat = 1]]]]]])
; Parameter(s):  $sPath = optional: path to generate filelist for, multi paths separated with semicolon (ex: "C:\Tmp;D:\Temp")
;                           if no path is given then @ScriptDir is used
;                  $sFilter = optional: The filter to use. (default: "*")
;                             multi filters separated with semicolon (ex: *.exe; *.txt will find all .exe and .txt files)
;                             (Search the Autoit3 manual for the word "WildCards" for details)
;                  $iSrchType = Optional: specifies whether to return files, folders or both
;                           0 = (Default) Return both files and folders
;                           1 = Return files only
;                           2 = Return folders only
;                           $iSrchType + 4 = Return Filenames and/or Folders incl full Path
;                  $bRecursiv = optional: true: recursive search in rootdir and subdirs
;                                         False (default): search only in rootdir
;                  $sExclude = optional: exclude a file/folder from the list by all or part of its name, various statements delimited with semicolon
;                              (ex: Unins* will remove all files/folders that start with Unins)
;                  $iFormat =  optional: return format
;                              0 = String ( "|" delimited)
;                              1 = (default) one-dimensional array, array[0] = number of files\folders returned
;                              2 = one-dimensional array, 0-based
; Requirement(s):   none
; Return Value(s):  on success: string or array (dependent on $iFormat)
; Author(s):        bernd670, Tlem, Spiff59, Zedna, KaFu, SmOke_N, GEOSoft, Ascend4nt, BaKaMu
; ====================================================================================================




Func _FileListToArrayEx3($sPath = @ScriptDir, $sFilter = "*", $iSrchType = 0, $iPathType = 0, $bRecursiv = False, $sExclude = "", $iFormat = 1, $wrk = "")
  Local $hSearch, $iPCount, $iFCount, $sFile, $SrchType = 0, $sFileList = "", $sTExclude = "", $wrk2

  If $sPath = -1 Or $sPath = Default Then $sPath = @ScriptDir
  If $sFilter = -1 Or $sFilter = Default Then $sFilter = "*"
  If $iSrchType = -1 Or $iSrchType = Default Then $iSrchType = 0
  If $bRecursiv = Default Then $bRecursiv = False
  If $sExclude = -1 Or $sExclude = Default Then $sExclude = ""
  If $iFormat = -1 Or $iFormat = Default Then $iFormat = 1

;separate multi path
  Local $aPath = StringSplit($sPath, ';')
;separate multi filter
  Local $aFilter = StringSplit($sFilter, ';')

  If $sExclude Then

  ;prepare $sTExclude
  ;Strip leading and trailing spaces and spaces between semi colon delimiter
    $sTExclude = StringStripWS(StringRegExpReplace($sExclude, "\s*;\s*", ";"), 3)
  ;convert $sExclude to fit StringRegExp (not perfect but useable)
    $sTExclude = StringRegExpReplace($sTExclude, '([\Q\.+[^]$(){}=!\E])', '\\$1');thanks KaFu and Ascend4nt
    $sTExclude = StringReplace($sTExclude, "?", ".")
    $sTExclude = StringReplace($sTExclude, "*", ".*?")
    $sTExclude = StringReplace($sTExclude, ";", "|")

    For $iPCount = 1 To $aPath[0]
      Local $sPathItem = StringStripWS($aPath[$iPCount], 3);Strip leading and trailing spaces
      Local $sDelim = "|";reset $sDelim

      If StringRight($sPathItem, 1) <> "\" Then $sPathItem = $sPathItem & "\";check for trailing "\"

    ;return full-path
      If $iPathType = 2 Then $sDelim &= $sPathItem

    ;perform the search
      For $iFCount = 1 To $aFilter[0]
        Local $FilterItem = StringStripWS($aFilter[$iFCount], 3);Strip leading and trailing spaces
        If StringRegExp($FilterItem, "[\\/:<>|]") Then ContinueLoop;Look for bad chars
        $hSearch = FileFindFirstFile($sPathItem & $FilterItem)
        If @error Then ContinueLoop
        Switch $SrchType
          Case 0;Files and Folders
            While True
              $sFile = FileFindNextFile($hSearch)
              If @error Then ExitLoop
            ;check for exclude filename/folder
              If StringRegExp(StringRegExpReplace($sFile, "(.*?[\\/]+)*(.*?\z)", "\2"), "(?i)\A" & $sTExclude & "\z") Then ContinueLoop
              $sFileList &= $sDelim & $wrk & $sFile
            WEnd
          Case 1;Files Only
            While True
              $sFile = FileFindNextFile($hSearch)
              If @error Then ExitLoop
              If @extended Then ContinueLoop;bypass folder (for Autoit versions > 3.3.0.0)
            ;check for exclude filename/folder
              If StringRegExp(StringRegExpReplace($sFile, "(.*?[\\/]+)*(.*?\z)", "\2"), "(?i)\A" & $sTExclude & "\z") Then ContinueLoop
              $sFileList &= $sDelim & $wrk & $sFile
            WEnd
          Case 2;Folders Only
            While True
              $sFile = FileFindNextFile($hSearch)
              If @error Then ExitLoop
              If @extended = 0 Then ContinueLoop;bypass file (for Autoit versions > 3.3.0.0)
            ;check for exclude filename/folder
              If StringRegExp(StringRegExpReplace($sFile, "(.*?[\\/]+)*(.*?\z)", "\2"), "(?i)\A" & $sTExclude & "\z") Then ContinueLoop
              $sFileList &= $sDelim & $wrk & $sFile
            WEnd
          Case Else
            Return SetError(3, 3, "")
        EndSwitch
        FileClose($hSearch)
      Next

    ;---------------

    ;optional do a recursive search
      If $bRecursiv Then
        $hSearch = FileFindFirstFile($sPathItem & "*.*")
        If Not @error Then
          While True
            $sFile = FileFindNextFile($hSearch)
            If @error Then ExitLoop
            If @extended = 0 Then ContinueLoop;bypass file (for Autoit versions > 3.3.0.0)
          ;check for exclude folder
            If StringRegExp(StringRegExpReplace($sFile, "(.*?[\\/]+)*(.*?\z)", "\2"), "(?i)\A" & $sTExclude & "\z") Then ContinueLoop
          ;call recursive search
            $sFileList &= _FileListToArrayEx3($sPathItem & $sFile, $sFilter, $iSrchType, $bRecursiv, $sExclude, 0)
          WEnd
          FileClose($hSearch)
        EndIf
      EndIf

    Next;$iPCount

  Else;If Not $sExclude

    For $iPCount = 1 To $aPath[0]
      Local $sPathItem = StringStripWS($aPath[$iPCount], 3);Strip leading and trailing spaces
      Local $sDelim = "|";reset $sDelim

      If StringRight($sPathItem, 1) <> "\" Then $sPathItem = $sPathItem & "\";check for trailing "\"

    ;return full-path
      If $iPathType = 2 Then $sDelim &= $sPathItem

    ;perform the search
      For $iFCount = 1 To $aFilter[0]
        Local $FilterItem = StringStripWS($aFilter[$iFCount], 3);Strip leading and trailing spaces
        If StringRegExp($FilterItem, "[\\/:<>|]") Then ContinueLoop;Look for bad chars
        $hSearch = FileFindFirstFile($sPathItem & $FilterItem)
        If @error Then ContinueLoop
        Switch $SrchType
          Case 0;Files and Folders
            While True
              $sFile = FileFindNextFile($hSearch)
              If @error Then ExitLoop
              $sFileList &= $sDelim & $wrk & $sFile
            WEnd
          Case 1;Files Only
            While True
              $sFile = FileFindNextFile($hSearch)
              If @error Then ExitLoop
              If @extended Then ContinueLoop;bypass folder (for Autoit versions > 3.3.0.0)
              $sFileList &= $sDelim & $wrk & $sFile
            WEnd
          Case 2;Folders Only
            While True
              $sFile = FileFindNextFile($hSearch)
              If @error Then ExitLoop
              If @extended = 0 Then ContinueLoop;bypass file (for Autoit versions > 3.3.0.0)
              $sFileList &= $sDelim & $wrk & $sFile
            WEnd
          Case Else
            Return SetError(3, 3, "")
        EndSwitch
        FileClose($hSearch)
      Next

    ;---------------

    ;optional do a recursive search
      If $bRecursiv Then
        $hSearch = FileFindFirstFile($sPathItem & "*.*")
        If Not @error Then
          While True
            $sFile = FileFindNextFile($hSearch)
            If @error Then ExitLoop
            If @extended = 0 Then ContinueLoop;bypass file (for Autoit versions > 3.3.0.0)
          ;call recursive search
            If $PathType = 1 Then $wrk2 = $wrk & $sFile & "\"
            $sFileList &= _FileListToArrayEx3($sPathItem & $sFile, $sFilter, $iSrchType, $iPathType, $bRecursiv, $sExclude, 0, $wrk2)
          WEnd
          FileClose($hSearch)
        EndIf
      EndIf

    Next;$iPCount

  EndIf;If $sExclude

;---------------

;Set according return value
  Switch $iFormat
    Case 0
      Return $sFileList
    Case 1
      If $sFileList = "" Then
        Local $aRet[1] = [0]
        Return $aRet
      Else
        Return StringSplit(StringTrimLeft($sFileList, 1), "|", $iFormat)
      EndIf
    Case 2
      If $sFileList = "" Then
        Return ""
      Else
        Return StringSplit(StringTrimLeft($sFileList, 1), "|", $iFormat)
      EndIf
  EndSwitch

EndFunc ;==>_FileListToArrayEx3

Share this post


Link to post
Share on other sites



Hello erik7426,

Melba23 wrote an excellent example and shared it with us here:

#835800

Realm


My Contributions: Unix Timestamp: Calculate Unix time, or seconds since Epoch, accounting for your local timezone and daylight savings time. RegEdit Jumper: A Small & Simple interface based on Yashied's Reg Jumper Function, for searching Hives in your registry.  

Share this post


Link to post
Share on other sites

Hello erik7426,

Melba23 wrote an excellent example and shared it with us here:

#835800

Realm

I tried your suggestion with similar results.

I used the following parameters with Melba23's function

$myResults = 1
;|$iReturn = 0 (Default) Return both files and folders
;|$iReturn = 1 Return files only
;|$iReturn = 2 Return folders only
$myRecur = 1
;|$fRecur = 0 (Default) Do not search in subfolders
;|$fRecur = 1 Search in subfolders
$mySort = 0
;|$fSort = 0 (Default) Not sorted
;|$fSort = 1 Sorted
$myReturnPath = 2
;|$sReturnPath = 0 File/folder name only
;|$sReturnPath = 1 (Default) Initial path not included
;|$sReturnPath = 2 Initial path included
$myExclusions = ""


$myList = _RecFileListToArray("K:\", "*.exe", $myResults, $myRecur, $mySort, $myReturnPath, $myExclusions)


_ArrayDisplay($myList)

It will find all EXE files in any sub-directory of the K drive, but it will not go beyond the initial sub-directory.

So, K:\Progam1\setup.exe it will find

BUT

K:\Program1\subprogram\setup.exe it will NOT find.

Share this post


Link to post
Share on other sites

erik7426,

The code you posted works fine for me when I run it on any one of my drives - I get every *.exe file in all the subfolders. ;)

Are you sure that K:\Program1\subprogram\setup.exe exists. :)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

erik7426,

The code you posted works fine for me when I run it on any one of my drives - I get every *.exe file in all the subfolders. ;)

Are you sure that K:\Program1\subprogram\setup.exe exists. :)

M23

Yes, I'm sure they exist. I just noticed the version requirement on your function. I am still using 3.3.0.0. I will have to go back and look at the script breaking changes that were made to subsequent versions of AutoIT. If I remember correctly there was a specific reason I didn't update past 3.3.0.0. I wish there was a solution for the version I am currently using...

Thanks

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

erik7426,

The problem is that your AutoIt version does not set @extended to indicate if the return from FileFindNextFile is a folder or a file. :)

Hang on while I search around for an older version of the UDF - although you really should update. ;)

M23

Edit:

Replace this line (about #147):

If @extended Then

with this:

If StringInStr(FileGetAttrib($sCurrentPath & $sName), "D") And ($sName <> "." Or $sName <> "..") Then

and replace this line (about #183):

$fFolder = @extended

with this:

$fFolder = 0
If StringInStr(FileGetAttrib($sCurrentPath & $sName), "D") And ($sName <> "." Or $sName <> "..") Then $fFolder = 1

The UDF should work for you now. However, it is much slower this way - as I said, you really should update. ;)

Edited by Melba23

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

erik7426,

The problem is that your AutoIt version does not set @extended to indicate if the return from FileFindNextFile is a folder or a file. ;)

Hang on while I search around for an older version of the UDF - although you really should update. :)

M23

OK. Looking back through the changes that have been made since 3.3.0.0, I think the reason I didn't upgrade was because of the removal of OnAutoItExit in version 3.3.4.0. I have several scripts that relied on that functionality and didn't really have the time to try to figure out an alternative. Does an equivalent of OnAutoItExit exist in the current version of AutoIT?

Share this post


Link to post
Share on other sites

erik7426,

Does an equivalent of OnAutoItExit exist in the current version of AutoIT?

OnAutoItExitRegister/Unregister - it lets you register several functions rather then just the one, and to unregister them if necessary. ;)

Did you see the changes I posted above which should get the UDF to work on 3.3.0.0? :)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

erik7426,

OnAutoItExitRegister/Unregister - it lets you register several functions rather then just the one, and to unregister them if necessary. ;)

Did you see the changes I posted above which should get the UDF to work on 3.3.0.0? :)

M23

Yes, I just ran the script with the changes above and it does work. It is really slow. Now that I know an elternative to OnAutoItExit exists I will probably update to see how much faster the function runs with the original code.

Thanks for all your help.

Share this post


Link to post
Share on other sites

erik7426,

My pleasure. ;)

By the way, when you reply please use the "Add Reply" button at the top and bottom of the page rather then the "Reply" button in the post itself. That way you do not get the contents of the previous post quoted in your reply and the whole thread becomes easier to read. :)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0