DStark Posted July 29, 2021 Share Posted July 29, 2021 Hello, I have found a very specific case where _FileListToArrayRec() hangs. The setup: Have a mapped network drive Put a file in a folder starting with a "-". For example, map a P drive and then create "P:\-test.txt" #include <File.au3> Opt("TrayIconDebug", 1) $files = _FileListToArrayRec("P:\test\sync", "*", $FLTAR_FILES, $FLTAR_RECUR) MsgBox(48, "Done", "Done") Running that code for me never hit's the "Done" message box. If you hover over the tray icon you can see it's stuck in File.au3 indefinitely. I copied _FileListToArrayRec() into my project and started debugging. It seems as though the files get added to the list, "." and ".." do every time as well which is why the While statement: While $asFolderSearchList[0] > 0 Never evaluates to false. If I turn of recursion, then the filter "*||.+" seems to fix this. Experimenting with ways to fix it with recursion enabled. However, this appears to be a bug to me. Note that this doesn't happen on local files. Link to comment Share on other sites More sharing options...
DStark Posted July 29, 2021 Author Share Posted July 29, 2021 Seems like if a file with "-" is in the folder, FileFindFirstFile() returns "." and ".." folders which only the DLL call variant of the code handles. See the following (poorly) instrumented ___FileListToArraRec(): expandcollapse popupFunc ___FileListToArrayRec($sFilePath, $sMask = "*", $iReturn = $FLTAR_FILESFOLDERS, $iRecur = $FLTAR_NORECUR, $iSort = $FLTAR_NOSORT, $iReturnPath = $FLTAR_RELPATH) If Not FileExists($sFilePath) Then Return SetError(1, 1, "") ; Check for Default keyword If $sMask = Default Then $sMask = "*" If $iReturn = Default Then $iReturn = $FLTAR_FILESFOLDERS If $iRecur = Default Then $iRecur = $FLTAR_NORECUR If $iSort = Default Then $iSort = $FLTAR_NOSORT If $iReturnPath = Default Then $iReturnPath = $FLTAR_RELPATH ; Check for valid recur value If $iRecur > 1 Or Not IsInt($iRecur) Then Return SetError(1, 6, "") Local $bLongPath = False ; Check for valid path If StringLeft($sFilePath, 4) == "\\?\" Then $bLongPath = True EndIf Local $sFolderSlash = "" ; Check if folders should have trailing \ and ensure that initial path does have one If StringRight($sFilePath, 1) = "\" Then $sFolderSlash = "\" Else $sFilePath = $sFilePath & "\" EndIf Local $asFolderSearchList[100] = [1] ; Add path to folder search list $asFolderSearchList[1] = $sFilePath Local $iHide_HS = 0, _ $sHide_HS = "" ; Check for H or S omitted If BitAND($iReturn, 4) Then $iHide_HS += 2 $sHide_HS &= "H" $iReturn -= 4 EndIf If BitAND($iReturn, 8) Then $iHide_HS += 4 $sHide_HS &= "S" $iReturn -= 8 EndIf Local $iHide_Link = 0 ; Check for link/junction omitted If BitAND($iReturn, 16) Then $iHide_Link = 0x400 $iReturn -= 16 EndIf Local $iMaxLevel = 0 ; If required, determine \ count for max recursive level setting If $iRecur < 0 Then StringReplace($sFilePath, "\", "", 0, $STR_NOCASESENSEBASIC) $iMaxLevel = @extended - $iRecur EndIf Local $sExclude_List = "", $sExclude_List_Folder = "", $sInclude_List = "*" ; Check mask parameter Local $aMaskSplit = StringSplit($sMask, "|") ; Check for multiple sections and set values Switch $aMaskSplit[0] Case 3 $sExclude_List_Folder = $aMaskSplit[3] ContinueCase Case 2 $sExclude_List = $aMaskSplit[2] ContinueCase Case 1 $sInclude_List = $aMaskSplit[1] EndSwitch Local $sInclude_File_Mask = ".+" ; Create Include mask for files If $sInclude_List <> "*" Then If Not __FLTAR_ListToMask($sInclude_File_Mask, $sInclude_List) Then Return SetError(1, 2, "") EndIf Local $sInclude_Folder_Mask = ".+" ; 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 EndSwitch Case 2 ; Folders affected by mask $sInclude_Folder_Mask = $sInclude_File_Mask EndSwitch Local $sExclude_File_Mask = ":" ; Create Exclude List mask for files If $sExclude_List <> "" Then If Not __FLTAR_ListToMask($sExclude_File_Mask, $sExclude_List) Then Return SetError(1, 3, "") EndIf Local $sExclude_Folder_Mask = ":" ; Create Exclude mask for folders If $iRecur Then If $sExclude_List_Folder Then If Not __FLTAR_ListToMask($sExclude_Folder_Mask, $sExclude_List_Folder) Then Return SetError(1, 4, "") EndIf ; If folders only If $iReturn = 2 Then ; Folders affected by normal mask $sExclude_Folder_Mask = $sExclude_File_Mask EndIf Else ; Folders affected by normal mask $sExclude_Folder_Mask = $sExclude_File_Mask EndIf ; Verify other parameters If Not ($iReturn = 0 Or $iReturn = 1 Or $iReturn = 2) Then Return SetError(1, 5, "") If Not ($iSort = 0 Or $iSort = 1 Or $iSort = 2) Then Return SetError(1, 7, "") If Not ($iReturnPath = 0 Or $iReturnPath = 1 Or $iReturnPath = 2) Then Return SetError(1, 8, "") ; Prepare for DllCall if required If $iHide_Link Then Local $tFile_Data = DllStructCreate("struct;align 4;dword FileAttributes;uint64 CreationTime;uint64 LastAccessTime;uint64 LastWriteTime;" & _ "dword FileSizeHigh;dword FileSizeLow;dword Reserved0;dword Reserved1;wchar FileName[260];wchar AlternateFileName[14];endstruct") Local $hDLL = DllOpen('kernel32.dll'), $aDLL_Ret EndIf Local $asReturnList[100] = [0] Local $asFileMatchList = $asReturnList, $asRootFileMatchList = $asReturnList, $asFolderMatchList = $asReturnList Local $bFolder = False, _ $hSearch = 0, _ $sCurrentPath = "", $sName = "", $sRetPath = "" Local $iAttribs = 0, _ $sAttribs = '' Local $asFolderFileSectionList[100][2] = [[0, 0]] ; Search within listed folders While $asFolderSearchList[0] > 0 _Log("While no folders") Sleep(100) ; 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, $sFilePath, "") Case 2 ; Full path If $bLongPath Then $sRetPath = StringTrimLeft($sCurrentPath, 4) Else $sRetPath = $sCurrentPath EndIf EndSwitch ; Get search handle - use code matched to required listing If $iHide_Link Then ; Use DLL code $aDLL_Ret = DllCall($hDLL, 'handle', 'FindFirstFileW', 'wstr', $sCurrentPath & "*", 'struct*', $tFile_Data) If @error Or Not $aDLL_Ret[0] Then ContinueLoop EndIf $hSearch = $aDLL_Ret[0] Else ; Use native code $hSearch = FileFindFirstFile($sCurrentPath & "*") ; If folder empty move to next in list If $hSearch = -1 Then ContinueLoop EndIf EndIf ; 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 __FLTAR_AddToList($asFolderFileSectionList, $sRetPath, $asFileMatchList[0] + 1) EndIf $sAttribs = '' ; Search folder - use code matched to required listing While 1 _Log("While 1 start") Sleep(100) ; Use DLL code If $iHide_Link Then _Log("DLL call") Sleep(100) ; Use DLL code $aDLL_Ret = DllCall($hDLL, 'int', 'FindNextFileW', 'handle', $hSearch, 'struct*', $tFile_Data) ; Check for end of folder If @error Or Not $aDLL_Ret[0] Then ExitLoop EndIf ; Extract data $sName = DllStructGetData($tFile_Data, "FileName") ; Check for .. return - only returned by the DllCall If $sName = ".." Then ContinueLoop EndIf $iAttribs = DllStructGetData($tFile_Data, "FileAttributes") ; Check for hidden/system attributes and skip if found If $iHide_HS And BitAND($iAttribs, $iHide_HS) Then ContinueLoop EndIf ; Check for link attribute and skip if found If BitAND($iAttribs, $iHide_Link) Then ContinueLoop EndIf ; Set subfolder flag $bFolder = False If BitAND($iAttribs, 16) Then $bFolder = True EndIf Else _Log("No DLL call") Sleep(100) ; Reset folder flag $bFolder = False ; Use native code $sName = FileFindNextFile($hSearch, 1) ; Check for end of folder If @error Then _Log("error find next file") Sleep(100) ExitLoop EndIf $sAttribs = @extended ; Check for folder If StringInStr($sAttribs, "D") Then _Log("folder " & $sName) Sleep(100) $bFolder = True EndIf ; Check for Hidden/System If StringRegExp($sAttribs, "[" & $sHide_HS & "]") Then _Log("hidden/system") Sleep(100) ContinueLoop EndIf EndIf ; If folder then check whether to add to search list If $bFolder Then Select Case $iRecur < 0 ; Check recur depth _Log("recur < 0") StringReplace($sCurrentPath, "\", "", 0, $STR_NOCASESENSEBASIC) If @extended < $iMaxLevel Then _Log("max level ") ContinueCase ; Check if matched to masks EndIf Case $iRecur = 1 ; Full recur _Log("recur = 1") If Not StringRegExp($sName, $sExclude_Folder_Mask) Then ; Add folder unless excluded _Log("aded folder " & $sName & " to list ") __FLTAR_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 $bFolder Then If StringRegExp($sName, $sInclude_Folder_Mask) And Not StringRegExp($sName, $sExclude_Folder_Mask) Then __FLTAR_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 = $sFilePath Then __FLTAR_AddToList($asRootFileMatchList, $sRetPath & $sName) Else __FLTAR_AddToList($asFileMatchList, $sRetPath & $sName) EndIf EndIf EndIf Else ; Save directly in return list If $bFolder Then If $iReturn <> 1 And StringRegExp($sName, $sInclude_Folder_Mask) And Not StringRegExp($sName, $sExclude_Folder_Mask) Then __FLTAR_AddToList($asReturnList, $sRetPath & $sName & $sFolderSlash) EndIf Else _Log("Checking file add to list") If $iReturn <> 2 And StringRegExp($sName, $sInclude_File_Mask) And Not StringRegExp($sName, $sExclude_File_Mask) Then _Log("added file " & $sName & " to list ") __FLTAR_AddToList($asReturnList, $sRetPath & $sName) EndIf EndIf EndIf WEnd ; Close current search If $iHide_Link Then DllCall($hDLL, 'int', 'FindClose', 'ptr', $hSearch) Else FileClose($hSearch) EndIf WEnd ; Close the DLL if needed If $iHide_Link Then DllClose($hDLL) EndIf ; Sort results if required If $iSort Then Switch $iReturn Case 2 ; Folders only ; Check if any folders found If $asFolderMatchList[0] = 0 Then Return SetError(1, 9, "") ; Correctly size folder match list ReDim $asFolderMatchList[$asFolderMatchList[0] + 1] ; Copy size folder match array $asReturnList = $asFolderMatchList ; Simple sort list __ArrayDualPivotSort($asReturnList, 1, $asReturnList[0]) Case 1 ; Files only ; Check if any files found If $asRootFileMatchList[0] = 0 And $asFileMatchList[0] = 0 Then Return SetError(1, 9, "") If $iReturnPath = 0 Then ; names only so simple sort suffices ; Combine file match lists __FLTAR_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList) ; Simple sort combined file list __ArrayDualPivotSort($asReturnList, 1, $asReturnList[0]) Else ; Combine sorted file match lists __FLTAR_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList, 1) EndIf Case 0 ; Both files and folders ; Check if any root files or folders found If $asRootFileMatchList[0] = 0 And $asFolderMatchList[0] = 0 Then Return SetError(1, 9, "") If $iReturnPath = 0 Then ; names only so simple sort suffices ; Combine file match lists __FLTAR_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] _ArrayConcatenate($asReturnList, $asFolderMatchList, 1) ; Simple sort final list __ArrayDualPivotSort($asReturnList, 1, $asReturnList[0]) 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 __ArrayDualPivotSort($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 __ArrayDualPivotSort($asFolderMatchList, 1, $asFolderMatchList[0]) Local $sFolderToFind = "" ; Work through folder list For $i = 1 To $asFolderMatchList[0] ; Add folder to return list $asReturnList[$iNextInsertionIndex] = $asFolderMatchList[$i] $iNextInsertionIndex += 1 ; Format folder name for search If $sFolderSlash Then $sFolderToFind = $asFolderMatchList[$i] Else $sFolderToFind = $asFolderMatchList[$i] & "\" EndIf Local $iFileSectionEndIndex = 0, $iFileSectionStartIndex = 0 ; Find folder in FolderFileSectionList For $j = 1 To $asFolderFileSectionList[0][0] ; If found then deal with files If $sFolderToFind = $asFolderFileSectionList[$j][0] Then ; 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 __ArrayDualPivotSort($asFileMatchList, $iFileSectionStartIndex, $iFileSectionEndIndex) EndIf ; Add files to return list For $k = $iFileSectionStartIndex To $iFileSectionEndIndex $asReturnList[$iNextInsertionIndex] = $asFileMatchList[$k] $iNextInsertionIndex += 1 Next ExitLoop EndIf 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 ;==>_FileListToArrayRec Here is the output of that logging with "test.txt": While no folders While 1 start No DLL call Checking file add to list added file test.txt to list While 1 start No DLL call error find next file Here is the output with "-test.txt": While no folders While 1 start No DLL call Checking file add to list added file -test.txt to list While 1 start No DLL call folder . recur = 1 aded folder . to list While 1 start No DLL call folder .. recur = 1 aded folder .. to list While 1 start No DLL call error find next file You can see folder . and .. added to the list Link to comment Share on other sites More sharing options...
DStark Posted July 29, 2021 Author Share Posted July 29, 2021 OK, so seems adding "FLTAR_NOLINK" to the code fixes this. Working code: #include <File.au3> Opt("TrayIconDebug", 1) $files = _FileListToArrayRec("P:\test\sync", "*", $FLTAR_FILES + $FLTAR_NOLINK, $FLTAR_RECUR) MsgBox(48, "Done", "Done") Is this expected behavior? Link to comment Share on other sites More sharing options...
DStark Posted July 29, 2021 Author Share Posted July 29, 2021 Nevermind, the file doesn't show up if I have "FLTAR_NOLINK" added. In this case _ArrayDisplay() will not show the array since none was created. #include <File.au3> Opt("TrayIconDebug", 1) $files = _FileListToArrayRec("P:\test\sync", "*", $FLTAR_FILES + $FLTAR_NOLINK, $FLTAR_RECUR) _ArrayDisplay($files) MsgBox(48, "Done", "Done") Link to comment Share on other sites More sharing options...
DStark Posted July 29, 2021 Author Share Posted July 29, 2021 Ok, the filter "*||.*" seems to work. Still think "." and ".." should always be handled by _FileListToArrayRec() let me know what you guys think. #include <File.au3> Opt("TrayIconDebug", 1) $files = _FileListToArrayRec("P:\test\sync", "*||.*", $FLTAR_FILES, $FLTAR_RECUR) _ArrayDisplay($files) MsgBox(48, "Done", "Done") @Melba23 you're on the contributor list for File.au3 wondering your thoughts Link to comment Share on other sites More sharing options...
DStark Posted July 29, 2021 Author Share Posted July 29, 2021 Note I updated my example with my hacked version of ___FileListToArrayRec() In this I added If $sName = ".." Then ContinueLoop EndIf If $sName = "." Then ContinueLoop EndIf To the native code block and the function works. Also added a simple _Log function so that the code runs. Complete example: expandcollapse popup#include <File.au3> Opt("TrayIconDebug", 1) $files = ___FileListToArrayRec("P:\test\sync", "*", $FLTAR_FILES, $FLTAR_RECUR) _ArrayDisplay($files) MsgBox(48, "Done", "Done") Func _Log($message) ConsoleWrite($message & @CRLF) EndFunc Func ___FileListToArrayRec($sFilePath, $sMask = "*", $iReturn = $FLTAR_FILESFOLDERS, $iRecur = $FLTAR_NORECUR, $iSort = $FLTAR_NOSORT, $iReturnPath = $FLTAR_RELPATH) If Not FileExists($sFilePath) Then Return SetError(1, 1, "") ; Check for Default keyword If $sMask = Default Then $sMask = "*" If $iReturn = Default Then $iReturn = $FLTAR_FILESFOLDERS If $iRecur = Default Then $iRecur = $FLTAR_NORECUR If $iSort = Default Then $iSort = $FLTAR_NOSORT If $iReturnPath = Default Then $iReturnPath = $FLTAR_RELPATH ; Check for valid recur value If $iRecur > 1 Or Not IsInt($iRecur) Then Return SetError(1, 6, "") Local $bLongPath = False ; Check for valid path If StringLeft($sFilePath, 4) == "\\?\" Then $bLongPath = True EndIf Local $sFolderSlash = "" ; Check if folders should have trailing \ and ensure that initial path does have one If StringRight($sFilePath, 1) = "\" Then $sFolderSlash = "\" Else $sFilePath = $sFilePath & "\" EndIf Local $asFolderSearchList[100] = [1] ; Add path to folder search list $asFolderSearchList[1] = $sFilePath Local $iHide_HS = 0, _ $sHide_HS = "" ; Check for H or S omitted If BitAND($iReturn, 4) Then $iHide_HS += 2 $sHide_HS &= "H" $iReturn -= 4 EndIf If BitAND($iReturn, 8) Then $iHide_HS += 4 $sHide_HS &= "S" $iReturn -= 8 EndIf Local $iHide_Link = 0 ; Check for link/junction omitted If BitAND($iReturn, 16) Then $iHide_Link = 0x400 $iReturn -= 16 EndIf Local $iMaxLevel = 0 ; If required, determine \ count for max recursive level setting If $iRecur < 0 Then StringReplace($sFilePath, "\", "", 0, $STR_NOCASESENSEBASIC) $iMaxLevel = @extended - $iRecur EndIf Local $sExclude_List = "", $sExclude_List_Folder = "", $sInclude_List = "*" ; Check mask parameter Local $aMaskSplit = StringSplit($sMask, "|") ; Check for multiple sections and set values Switch $aMaskSplit[0] Case 3 $sExclude_List_Folder = $aMaskSplit[3] ContinueCase Case 2 $sExclude_List = $aMaskSplit[2] ContinueCase Case 1 $sInclude_List = $aMaskSplit[1] EndSwitch Local $sInclude_File_Mask = ".+" ; Create Include mask for files If $sInclude_List <> "*" Then If Not __FLTAR_ListToMask($sInclude_File_Mask, $sInclude_List) Then Return SetError(1, 2, "") EndIf Local $sInclude_Folder_Mask = ".+" ; 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 EndSwitch Case 2 ; Folders affected by mask $sInclude_Folder_Mask = $sInclude_File_Mask EndSwitch Local $sExclude_File_Mask = ":" ; Create Exclude List mask for files If $sExclude_List <> "" Then If Not __FLTAR_ListToMask($sExclude_File_Mask, $sExclude_List) Then Return SetError(1, 3, "") EndIf Local $sExclude_Folder_Mask = ":" ; Create Exclude mask for folders If $iRecur Then If $sExclude_List_Folder Then If Not __FLTAR_ListToMask($sExclude_Folder_Mask, $sExclude_List_Folder) Then Return SetError(1, 4, "") _Log("exclude list folder " & $sExclude_List_Folder) _Log("exclude list mask " & $sExclude_Folder_Mask) EndIf ; If folders only If $iReturn = 2 Then ; Folders affected by normal mask $sExclude_Folder_Mask = $sExclude_File_Mask EndIf Else ; Folders affected by normal mask $sExclude_Folder_Mask = $sExclude_File_Mask EndIf ; Verify other parameters If Not ($iReturn = 0 Or $iReturn = 1 Or $iReturn = 2) Then Return SetError(1, 5, "") If Not ($iSort = 0 Or $iSort = 1 Or $iSort = 2) Then Return SetError(1, 7, "") If Not ($iReturnPath = 0 Or $iReturnPath = 1 Or $iReturnPath = 2) Then Return SetError(1, 8, "") ; Prepare for DllCall if required If $iHide_Link Then Local $tFile_Data = DllStructCreate("struct;align 4;dword FileAttributes;uint64 CreationTime;uint64 LastAccessTime;uint64 LastWriteTime;" & _ "dword FileSizeHigh;dword FileSizeLow;dword Reserved0;dword Reserved1;wchar FileName[260];wchar AlternateFileName[14];endstruct") Local $hDLL = DllOpen('kernel32.dll'), $aDLL_Ret EndIf Local $asReturnList[100] = [0] Local $asFileMatchList = $asReturnList, $asRootFileMatchList = $asReturnList, $asFolderMatchList = $asReturnList Local $bFolder = False, _ $hSearch = 0, _ $sCurrentPath = "", $sName = "", $sRetPath = "" Local $iAttribs = 0, _ $sAttribs = '' Local $asFolderFileSectionList[100][2] = [[0, 0]] ; Search within listed folders While $asFolderSearchList[0] > 0 _Log("While no folders") Sleep(100) ; 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, $sFilePath, "") Case 2 ; Full path If $bLongPath Then $sRetPath = StringTrimLeft($sCurrentPath, 4) Else $sRetPath = $sCurrentPath EndIf EndSwitch ; Get search handle - use code matched to required listing If $iHide_Link Then ; Use DLL code $aDLL_Ret = DllCall($hDLL, 'handle', 'FindFirstFileW', 'wstr', $sCurrentPath & "*", 'struct*', $tFile_Data) If @error Or Not $aDLL_Ret[0] Then ContinueLoop EndIf $hSearch = $aDLL_Ret[0] Else ; Use native code $hSearch = FileFindFirstFile($sCurrentPath & "*") ; If folder empty move to next in list If $hSearch = -1 Then ContinueLoop EndIf EndIf ; 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 __FLTAR_AddToList($asFolderFileSectionList, $sRetPath, $asFileMatchList[0] + 1) EndIf $sAttribs = '' ; Search folder - use code matched to required listing While 1 _Log("While 1 start") Sleep(100) ; Use DLL code If $iHide_Link Then _Log("DLL call") Sleep(100) ; Use DLL code $aDLL_Ret = DllCall($hDLL, 'int', 'FindNextFileW', 'handle', $hSearch, 'struct*', $tFile_Data) ; Check for end of folder If @error Or Not $aDLL_Ret[0] Then ExitLoop EndIf ; Extract data $sName = DllStructGetData($tFile_Data, "FileName") ; Check for .. return - only returned by the DllCall If $sName = ".." Then ContinueLoop EndIf $iAttribs = DllStructGetData($tFile_Data, "FileAttributes") ; Check for hidden/system attributes and skip if found If $iHide_HS And BitAND($iAttribs, $iHide_HS) Then ContinueLoop EndIf ; Check for link attribute and skip if found If BitAND($iAttribs, $iHide_Link) Then ContinueLoop EndIf ; Set subfolder flag $bFolder = False If BitAND($iAttribs, 16) Then $bFolder = True EndIf Else _Log("No DLL call") Sleep(100) ; Reset folder flag $bFolder = False ; Use native code $sName = FileFindNextFile($hSearch, 1) ; Check for end of folder If @error Then _Log("error find next file") Sleep(100) ExitLoop EndIf ;- ADDED CODE ;- ADDED CODE ;- ADDED CODE If $sName = ".." Then ContinueLoop EndIf If $sName = "." Then ContinueLoop EndIf ;- ADDED CODE ;- ADDED CODE ;- ADDED CODE $sAttribs = @extended ; Check for folder If StringInStr($sAttribs, "D") Then _Log("folder " & $sName) Sleep(100) $bFolder = True EndIf ; Check for Hidden/System If StringRegExp($sAttribs, "[" & $sHide_HS & "]") Then _Log("hidden/system") Sleep(100) ContinueLoop EndIf EndIf ; If folder then check whether to add to search list If $bFolder Then Select Case $iRecur < 0 ; Check recur depth _Log("recur < 0") StringReplace($sCurrentPath, "\", "", 0, $STR_NOCASESENSEBASIC) If @extended < $iMaxLevel Then _Log("max level ") ContinueCase ; Check if matched to masks EndIf Case $iRecur = 1 ; Full recur _Log("recur = 1") If Not StringRegExp($sName, $sExclude_Folder_Mask) Then ; Add folder unless excluded _Log("aded folder " & $sName & " to list ") __FLTAR_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 $bFolder Then If StringRegExp($sName, $sInclude_Folder_Mask) And Not StringRegExp($sName, $sExclude_Folder_Mask) Then __FLTAR_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 = $sFilePath Then __FLTAR_AddToList($asRootFileMatchList, $sRetPath & $sName) Else __FLTAR_AddToList($asFileMatchList, $sRetPath & $sName) EndIf EndIf EndIf Else ; Save directly in return list If $bFolder Then If $iReturn <> 1 And StringRegExp($sName, $sInclude_Folder_Mask) And Not StringRegExp($sName, $sExclude_Folder_Mask) Then __FLTAR_AddToList($asReturnList, $sRetPath & $sName & $sFolderSlash) EndIf Else _Log("Checking file add to list") If $iReturn <> 2 And StringRegExp($sName, $sInclude_File_Mask) And Not StringRegExp($sName, $sExclude_File_Mask) Then _Log("added file " & $sName & " to list ") __FLTAR_AddToList($asReturnList, $sRetPath & $sName) EndIf EndIf EndIf WEnd ; Close current search If $iHide_Link Then DllCall($hDLL, 'int', 'FindClose', 'ptr', $hSearch) Else FileClose($hSearch) EndIf WEnd ; Close the DLL if needed If $iHide_Link Then DllClose($hDLL) EndIf ; Sort results if required If $iSort Then Switch $iReturn Case 2 ; Folders only ; Check if any folders found If $asFolderMatchList[0] = 0 Then Return SetError(1, 9, "") ; Correctly size folder match list ReDim $asFolderMatchList[$asFolderMatchList[0] + 1] ; Copy size folder match array $asReturnList = $asFolderMatchList ; Simple sort list __ArrayDualPivotSort($asReturnList, 1, $asReturnList[0]) Case 1 ; Files only ; Check if any files found If $asRootFileMatchList[0] = 0 And $asFileMatchList[0] = 0 Then Return SetError(1, 9, "") If $iReturnPath = 0 Then ; names only so simple sort suffices ; Combine file match lists __FLTAR_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList) ; Simple sort combined file list __ArrayDualPivotSort($asReturnList, 1, $asReturnList[0]) Else ; Combine sorted file match lists __FLTAR_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList, 1) EndIf Case 0 ; Both files and folders ; Check if any root files or folders found If $asRootFileMatchList[0] = 0 And $asFolderMatchList[0] = 0 Then Return SetError(1, 9, "") If $iReturnPath = 0 Then ; names only so simple sort suffices ; Combine file match lists __FLTAR_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] _ArrayConcatenate($asReturnList, $asFolderMatchList, 1) ; Simple sort final list __ArrayDualPivotSort($asReturnList, 1, $asReturnList[0]) 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 __ArrayDualPivotSort($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 __ArrayDualPivotSort($asFolderMatchList, 1, $asFolderMatchList[0]) Local $sFolderToFind = "" ; Work through folder list For $i = 1 To $asFolderMatchList[0] ; Add folder to return list $asReturnList[$iNextInsertionIndex] = $asFolderMatchList[$i] $iNextInsertionIndex += 1 ; Format folder name for search If $sFolderSlash Then $sFolderToFind = $asFolderMatchList[$i] Else $sFolderToFind = $asFolderMatchList[$i] & "\" EndIf Local $iFileSectionEndIndex = 0, $iFileSectionStartIndex = 0 ; Find folder in FolderFileSectionList For $j = 1 To $asFolderFileSectionList[0][0] ; If found then deal with files If $sFolderToFind = $asFolderFileSectionList[$j][0] Then ; 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 __ArrayDualPivotSort($asFileMatchList, $iFileSectionStartIndex, $iFileSectionEndIndex) EndIf ; Add files to return list For $k = $iFileSectionStartIndex To $iFileSectionEndIndex $asReturnList[$iNextInsertionIndex] = $asFileMatchList[$k] $iNextInsertionIndex += 1 Next ExitLoop EndIf 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 ;==>_FileListToArrayRec Musashi 1 Link to comment Share on other sites More sharing options...
DStark Posted July 29, 2021 Author Share Posted July 29, 2021 Apologies I said in the original code to create P:\-test.exe, but for my purposes I needed it to be P:\test\sync\-test.exe Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted July 29, 2021 Moderators Share Posted July 29, 2021 DStark, We have run into problems with the UDF returning "." and ".." before and we thought we had fixed it - obviously not! I will take a look at the code (and your suggested fixes) to see if we can put this to bed for once and for all. Thanks for letting us know about the problem. 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 Link to comment Share on other sites More sharing options...
DStark Posted July 29, 2021 Author Share Posted July 29, 2021 Hi Melba, Thanks for the reply! FYI you may enjoy seeing this - during testing I tried to put "." for the folder exclude filter and it gives me this... Note there is only P:\test\sync\-test.txt. This is probably a different issue worth investigating while you're at it 🤣 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