#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Change2CUI=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

;
; sort keys in dictionary
; https://stackoverflow.com/questions/35505931/sort-keys-in-dictionary
;

#include-once
#include <FileConstants.au3>
#include <Array.au3>

Global $sFileSelectFolder = FileSelectFolder("Verzeichnis auswählen", "c:\")

; damit bekommen alle Pfade (ohne Dateien) hinten einen \ dazu - damit weiß ich das das ein Directory ==> Verzeichniszwischenblatt, ist
$sFileSelectFolder = $sFileSelectFolder & "\"

Local $oFiles = _FileListToDict($sFileSelectFolder, True, -3, False, 100, 0)

ConsoleWrite(@CRLF & @CRLF)
ConsoleWrite(@extended & " Dateien" & @CRLF)

If Not @error Then
	For $vFiles In $oFiles.Keys
		ConsoleWrite($vFiles & ", " & $oFiles($vFiles) & @CRLF)
	Next
EndIf

MsgBox(0x0, "", 'Items Count : ' & $oFiles.count)



;===============================================================================
;
; Function Name:   _FileListToDict($vFolder[, $bRec[, $iFileInformation[, $bRelative[, $iMaxDepth[, $iFilesAndOrFolders]]]]])
; Description:     Speichert Dateien, optional mit einer gewählten Eigenschaft, in einerm Dictionary-Objekt.
; Parameter(s):    $vFolder = Ein Startverzeichnis oder ein eindimensionales Array von Startverzeichnissen für die Dateisuche.
;                  $bRec = Rekursive Dateisuche bei $bRec = True (Standardwert)
;                  $iFileInformation = In $oFiles.Items kann eine gewählte Datei-Information gespeichert werden.
;				   |-1 = Keine Information. $oFiles.Items = True. (Standardwert).
;				   | 0 = Bearbeitungszeitpunkt
;				   | 1 = Erstellzeitpunkt
;				   | 2 = Letzte Zugriffszeit
;				   |-2 = Dateigröße in bytes
;				   |-3 = Dateigröße in größter erreichter Einheit.
;                  $bRelative = $oFiles.Keys haben relativem Dateipfad bei $bRelative = True (Standardwert = False).
;                  $iMaxDepth = Anzahl der ausgelesenen Unterverzeichnisse unterhalb der/des Startverzeichniss(es) (Standardwert = 100).
;                  $iFilesAndOrFolders = $oFiles.Keys haben relativem Dateipfad bei $bRelative = True (Standardwert = False).
;				   |0 = Dateien und Ordner
;				   |1 = Nur Dateien
;				   |2 = Nur Ordner
; Return Value(s): Zurückgegeben wird ein Objekt mit den kompletten oder relativen Dateipfaden als Key (abhängig von $bRelative)
;                  und in Abhängigkeit von $iFileInformation mit True oder Datei-Information als Item.
;
;                  @error kann folgende Werte annehmen (Kombinationen möglich, BitOr):
;                         0 = kein Fehler aufgetreten, alle Dateien wurden korrekt kopiert
;                         1 = Der übergebene Pfad ist kein existierendes Verzeichnis
;                         2 = Startverzeichnis-Array ist nicht eindimensional
; Author(s):       autoiter
; Modified:
; Remarks:
;===============================================================================                               beides
Func _FileListToDict($vFolder, $bRec = True, $iFileInformation = -1, $bRelative = False, $iMaxDepth = 100, $iFilesOrFolders = 0)

	If $iFileInformation <> -1 Then
		Switch $iFileInformation
			Case 0
				$iFileInformation = $FT_MODIFIED
			Case 1
				$iFileInformation = $FT_CREATED
			Case 2
				$iFileInformation = $FT_ACCESSED
			Case -2, -3 ; FileGetSize
			Case Else
				$iFileInformation = -1
		EndSwitch
	EndIf

	If $bRec Then
		If $iMaxDepth < 1 Or Int($iMaxDepth) = 0 Then $iMaxDepth = 1
	EndIf

	If IsArray($vFolder) Then
		If UBound($vFolder, 2) > 1 Then Return SetError(2)
		Local $iMaxIndex = UBound($vFolder)
		Local $aFolder[$iMaxIndex], $iCount = 0
		For $i = 0 To $iMaxIndex - 1
			If Not StringInStr(FileGetAttrib($vFolder[$i]), "D") Then ContinueLoop
			$aFolder[$iCount] = $vFolder[$i]
			$iCount += 1
		Next
		If $iCount = 0 Then Return SetError(1)
		$iMaxIndex = $iCount
		ReDim $aFolder[$iMaxIndex]
	Else
		Local $iMaxIndex = 1
		Local $aFolder[$iMaxIndex]
		If Not StringInStr(FileGetAttrib($vFolder), "D") Then Return SetError(1)
		$aFolder[0] = $vFolder
	EndIf

	Local $oFiles = ObjCreate("Scripting.Dictionary")

	Local $aSearchFile[256], $sFile, $iDepth, $iInfo, $sFolder, $sStartFolder

	For $i = 0 To $iMaxIndex - 1
		$iDepth = 1

		$sFolder = StringRegExpReplace($aFolder[$i], "\\$", "")

		$sStartFolder = $sFolder ; Startfolder wird zur Bildung des vollen Dateipfades gespeichert.

		$aSearchFile[$iDepth] = FileFindFirstFile($sFolder & "\*.*")
		While $iDepth >= 0 ; In dieser Schleife werden alle Dateien/Ordner abgehandelt
			$sFile = FileFindNextFile($aSearchFile[$iDepth])
			If @extended And $bRec And $iDepth < $iMaxDepth Then ; Wenn es sich um ein Ordner handelt wird in diesem weiter gesucht - solange max. Rekursionstiefe nicht erreicht.
				$iDepth += 1
				$sFolder &= "\" & $sFile
				If $iFilesOrFolders <> 1 Then $oFiles($sFolder) = $iInfo
				$aSearchFile[$iDepth] = FileFindFirstFile($sFolder & "\*.*")
			ElseIf @error Then ; Wenn keine Dateien mehr im Ordner vorhanden sind wird das "Handle" Freigegeben
				FileClose($aSearchFile[$iDepth])
				$iDepth -= 1
				$sFolder = StringRegExpReplace($sFolder, "\\[^\\]*$", "")
			Else
				If $iFilesOrFolders <> 0 Then
					If $iFilesOrFolders = 1 And StringInStr(FileGetAttrib($sFolder & "\" & $sFile), "D") Then ContinueLoop
					If $iFilesOrFolders = 2 And Not StringInStr(FileGetAttrib($sFolder & "\" & $sFile), "D") Then ContinueLoop
				EndIf

				If $iFileInformation <> -1 Then
					$iInfo = ""
					Switch $iFileInformation
						Case 0, 1, 2
							$iInfo = FileGetTime($sFolder & "\" & $sFile, $iFileInformation, $FT_STRING)
						Case -2
							If Not StringInStr(FileGetAttrib($sFolder & "\" & $sFile), "D") Then $iInfo = FileGetSize($sFolder & "\" & $sFile)
						Case -3
							If Not StringInStr(FileGetAttrib($sFolder & "\" & $sFile), "D") Then $iInfo = __FileListToDict_ByteSuffix(FileGetSize($sFolder & "\" & $sFile))
					EndSwitch
					If @error Then ContinueLoop
					If Not $bRelative Then
						$oFiles($sFolder & "\" & $sFile) = $iInfo
					Else
						$oFiles(StringReplace($sFolder, $sStartFolder, "") & "\" & $sFile) = $iInfo
					EndIf
				Else
					If Not $bRelative Then
						$oFiles($sFolder & "\" & $sFile) = True
					Else
						$oFiles(StringReplace($sFolder, $sStartFolder, "") & "\" & $sFile) = True
					EndIf
				EndIf
			EndIf
		WEnd
	Next
	Return SetError(0, $oFiles.Count, $oFiles)
EndFunc   ;==>_FileListToDict


Func __FileListToDict_ByteSuffix($iBytes) ; Aus der Hilfe zu FileGetSize.
	Local $iIndex = 0, $aArray = [' bytes', ' kB', ' MB', ' GB', ' TB', ' PB', ' EB', ' ZB', ' YB']
	While $iBytes > 1023
		$iIndex += 1
		$iBytes /= 1024
	WEnd
	Return Round($iBytes) & $aArray[$iIndex]
EndFunc   ;==>__FileListToDict_ByteSuffix

