• Offizieller Beitrag

    Ich weiß, dass es bereits Hunderte von Datei-Suchprogrammen gibt und es gibt sogar schnellere als dieses hier, aber ich hatte mal Lust sowas selbst zu schreiben und wollte mal sehen, wie schnell oder langsam das mit AutoIt wird.
    Erstaunt war ich dann schon, dass die Suche gar nicht so lange dauert. Ich habe mal einen beliebigen Suchbegriff (*kugel*) genommen und ihn auf meine 4 Festplatten (>560.000 Dateien) losgelassen. Die Suche hat dann etwa 1 Minute und 30 Sekunden gedauert und ich hatte 75 Treffer. Je mehr Treffer, desto länger dauert die Suche.
    Man kann diverse Einstellungen vornehmen (Erklärung über Tooltips).
    Das Programm ist noch nicht ganz fertig. Die Einstellungen werden noch nicht gespeichert, aber ansonsten sollte alles funktionieren.
    Wenn jemand Fehler findet oder Verbesserungsvorschläge hat, immer her damit. :D

    Screenshot:
    autoit.de/wcf/attachment/23640/

    Spoiler anzeigen
    [autoit]


    #NoTrayIcon
    #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_Icon=prog.ico
    #AutoIt3Wrapper_Outfile=FileSearch.exe
    #AutoIt3Wrapper_UseUpx=n
    #AutoIt3Wrapper_UseX64=n
    #AutoIt3Wrapper_Res_Description=FileSearch
    #AutoIt3Wrapper_Res_Fileversion=0.9.0.1
    #AutoIt3Wrapper_Res_LegalCopyright=Oscar (http://www.autoit.de)
    #AutoIt3Wrapper_Res_Language=1031
    #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
    #include <ButtonConstants.au3>
    #include <ComboConstants.au3>
    #include <GuiComboBox.au3>
    #include <Date.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <GuiListView.au3>
    #include <GuiStatusBar.au3>
    #include <ListViewConstants.au3>
    #include <Misc.au3>
    #include <StaticConstants.au3>
    #include <StructureConstants.au3>
    #include <WinAPI.au3>
    #include <WindowsConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt('GUIOnEventMode', 1)
    Opt('GUICloseOnESC', 0)

    [/autoit] [autoit][/autoit] [autoit]

    Global $sTitle = 'FileSearch'
    Global $sVersion = '0.9.0.1'
    _Singleton($sTitle & $sVersion)

    [/autoit] [autoit][/autoit] [autoit]

    Global $sDate = '23.10.2013'
    Global $sAppDir = @AppDataDir & '\FileSearch\'
    If Not FileExists($sAppDir) Then DirCreate($sAppDir)
    Global $sIniFile = $sAppDir & 'FileSearch.ini'
    Global $fStartSearch = False, $iFoundCount = 0, $iAllFiles = 0, $iSearchTimer, $aFileList[1][1]
    Global $aSearchExt[6] = ['', '\.(mpg|mpeg|avi|mkv|mp4)', '\.(wav|wma|mp1|mp2|mp3|ogg|aif|aiff|ac3|rm)', '\.(bmp|jpg|gif|png|tif|tiff)', '\.(txt|pdf|ini|reg|nfo)', '\.(doc|docx|pps|ppt|odt|ods|odp)'], $sSearchExt = $aSearchExt[0]

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Global $hGui = GUICreate(StringFormat('%s v%3.3s', $sTitle, $sVersion), 1000, 585)
    GUISetOnEvent($GUI_EVENT_CLOSE, '_CloseGui')
    GUISetIcon(@ScriptDir & '\FileSearch.exe', 0)
    GUISetBkColor(0xBBBBBB)

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlCreateGroup('Einstellungen:', 10, 6, 980, 120)
    GUICtrlSetFont(-1, 10, 400, 0, 'Arial')
    Global $idSetCaseSensitiv = GUICtrlCreateCheckbox('Groß-/Kleinschreibung beachten', 25, 24, 280, 22)
    GUICtrlSetFont(-1, 11, 400, 0, 'Arial')
    GUICtrlSetTip(-1, 'Ist der Haken gesetzt, wird bei der Suche die Groß-/Kleinschreibung des Suchbegriffs beachtet.' & @CR & 'Ohne Haken ist die Groß-/Kleinschreibung egal.', '', 1, 1)
    Global $idSetHiddenView = GUICtrlCreateCheckbox('Versteckte und Systemdateien anzeigen', 25, 48, 280, 22)
    GUICtrlSetFont(-1, 11, 400, 0, 'Arial')
    GUICtrlSetTip(-1, 'Ist der Haken gesetzt, werden auch versteckte und Systemdateien angezeigt.', '', 1, 1)
    Global $idSetRegEx = GUICtrlCreateCheckbox('RegEx verwenden (für Profis)', 25, 72, 260, 22)
    GUICtrlSetFont(-1, 11, 400, 0, 'Arial')
    GUICtrlSetTip(-1, 'Der Suchbegriff kann einen "regulären Ausdruck" enthalten.' & @CR & 'Damit lassen sich komplexere Suchmuster erstellen.' & @CR & 'Weitere Informationen zu RegEx findet man im Internet.', '', 1, 1)
    Global $idSetView = GUICtrlCreateCheckbox('Ergebnisse sofort anzeigen', 25, 96, 280, 22)
    GUICtrlSetFont(-1, 11, 400, 0, 'Arial')
    GUICtrlSetTip(-1, 'Die Suchergebnisse werden sofort angezeigt und können auch schon per Doppelklick aufgerufen werden,' & @CR & 'aber die Suche dauert länger, wenn viele Dateien gefunden werden.', '', 1, 1)
    GUICtrlSetState(-1, $GUI_CHECKED)
    Global $idSetDrive = GUICtrlCreateRadio('Laufwerke:', 310, 23, 90, 25)
    GUICtrlSetFont(-1, 11, 400, 0, 'Arial')
    GUICtrlSetTip(-1, 'Hier können die Laufwerke ausgewählt werden, die durchsucht werden sollen.' & @CR & 'Standardmäßig sind alle Festplatten ausgewählt.', '', 1, 1)
    GUICtrlSetOnEvent(-1, '_ChangeSearchPath')
    Global $aidDrives
    _CreateDrives()
    Global $idSetDir = GUICtrlCreateRadio('Verzeichnis:', 310, 95, 90, 25)
    GUICtrlSetFont(-1, 11, 400, 0, 'Arial')
    GUICtrlSetTip(-1, 'Hier kann ein Verzeichnis ausgewählt werden.' & @CR & 'Dieses Verzeichnis wird dann rekursiv (inkl. Unterverzeichnissen) durchsucht.', '', 1, 1)
    GUICtrlSetOnEvent(-1, '_ChangeSearchPath')
    Global $idSetSearchDir = GUICtrlCreateLabel('', 410, 96, 520, 22, $SS_SUNKEN)
    GUICtrlSetFont(-1, 12, 400, 0, 'Tahoma')
    GUICtrlSetBkColor($idSetSearchDir, 0xCCCCCC)
    GUICtrlSetTip(-1, 'Dieses Verzeichnis wird rekursiv (inkl. Unterverzeichnissen) durchsucht.', '', 1, 1)
    GUICtrlSetState(-1, $GUI_DISABLE)
    Global $idGetSearchDir = GUICtrlCreateButton('...', 931, 94, 36, 26)
    GUICtrlSetFont(-1, 12, 400, 0, 'Tahoma')
    GUICtrlSetTip(-1, 'Öffnet eine Verzeichnis-Auswahlbox.', '', 1, 1)
    GUICtrlSetOnEvent(-1, '_SelectSearchDir')
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUICtrlCreateGroup('', -99, -99, 1, 1)

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlCreateGroup('Suchbegriff: (Platzhalter: * = Null oder mehr beliebige Zeichen, ? = ein beliebiges Zeichen)', 10, 140, 980, 92)
    GUICtrlSetFont(-1, 10, 400, 0, 'Arial')
    GUICtrlCreateLabel('Suche auf folgende Dateiendungen beschränken:', 30, 201, 320, 28)
    GUICtrlSetFont(-1, 11, 400, 0, 'Arial')
    Global $idSearchExt = GUICtrlCreateCombo('Alle Dateien (*.*)', 360, 198, 440, 28, $CBS_DROPDOWNLIST)
    GUICtrlSetData(-1, 'Videodateien (*.mpg *.avi *.mkv *.mp4)')
    GUICtrlSetData(-1, 'Audiodateien (*.wav *.wma *.mp1 *.mp2 *.mp3 *.ogg *.aiff *.ac3 *.rm)')
    GUICtrlSetData(-1, 'Grafikdateien (*.bmp *.jpg *.gif *.png *.tif)')
    GUICtrlSetData(-1, 'Textdateien (*.txt *.pdf *.ini *.reg *.nfo)')
    GUICtrlSetData(-1, 'Officedateien (*.doc *.xls *.pps *.ppt *.odt *.ods *.odp)')
    GUICtrlSetFont(-1, 9, 400, 0, 'Tahoma')
    GUICtrlSetOnEvent(-1, '_GetSearchExt')
    Global $idSearchString = GUICtrlCreateInput('', 30, 168, 770, 22)
    GUICtrlSetFont(-1, 11, 400, 0, 'Tahoma')
    Global $idSearchStart = GUICtrlCreateButton('Start', 810, 166, 160, 54, $BS_DEFPUSHBUTTON)
    GUICtrlSetFont(-1, 10, 400, 0, 'Arial')
    GUICtrlSetImage(-1, 'shell32.dll', -23, 1)
    GUICtrlSetOnEvent(-1, '_StartSearch')
    GUICtrlCreateGroup('', -99, -99, 1, 1)

    [/autoit] [autoit][/autoit] [autoit]

    Global $idFoundGroup = GUICtrlCreateGroup('Gefundene Dateien:', 10, 248, 980, 300)
    GUICtrlSetFont(-1, 10, 400, 0, 'Arial')
    Global $idFileList = GUICtrlCreateListView('Dateiname|Erw.|Größe (Bytes)|Attr.|Erstellungsdatum|Änderungsdatum|Verzeichnis', 20, 272, 960, 265, $LVS_SHOWSELALWAYS)
    GUICtrlSetOnEvent(-1, '_SortFileList')
    Global $hFileList = GUICtrlGetHandle($idFileList)
    _GUICtrlListView_JustifyColumn($hFileList, 2, 1)
    Global $idCMFound = GUICtrlCreateContextMenu($idFileList)
    Global $idCMAllFiles = GUICtrlCreateMenuItem('Alle Dateinamen in eine Textdatei speichern', $idCMFound)
    GUICtrlSetOnEvent(-1, '_SaveFilenamesToTxt')
    Global $idCMMarkFiles = GUICtrlCreateMenuItem('Die markierten Dateinamen in eine Textdatei speichern', $idCMFound)
    GUICtrlSetOnEvent(-1, '_SaveFilenamesToTxt')
    GUICtrlCreateGroup('', -99, -99, 1, 1)

    [/autoit] [autoit][/autoit] [autoit]

    Global $hInfoIcon = _WinAPI_LoadShell32Icon(221)
    Global $hSearchIcon = _WinAPI_LoadShell32Icon(22)
    Global $hDiskIcon = _WinAPI_LoadShell32Icon(8)
    Global $hAttentionIcon = _WinAPI_LoadShell32Icon(77)
    Global $aParts[3] = [240,800, 840]
    Global $hStatus = _GUICtrlStatusBar_Create($hGui)
    _GUICtrlStatusBar_SetParts($hStatus, $aParts)

    [/autoit] [autoit][/autoit] [autoit]

    _GUICtrlListView_RegisterSortCallBack($hFileList) ; damit man das Listview (mit Klick auf die Spaltenüberschrift) sortieren kann
    ;~ _ChangeSearchPath()
    GUISetState()
    GUICtrlSetState($idSetDrive, $GUI_CHECKED)
    GUICtrlSetState($idSearchString, $GUI_FOCUS)

    [/autoit] [autoit][/autoit] [autoit]

    _GUICtrlStatusBar_SetIcon($hStatus, 0, $hInfoIcon)
    _GUICtrlStatusBar_SetText($hStatus, 'Bereit.', 0)
    GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')

    [/autoit] [autoit][/autoit] [autoit]

    While Sleep(20)
    If $fStartSearch Then _Search()
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _SaveFilenamesToTxt()
    Local $aSelItems, $aItems[1], $iItemCount = _GUICtrlListView_GetItemCount($hFileList), $sDefaultFilename, $sSaveFile, $hFile
    If $iItemCount = 0 Then Return ; wenn keine Einträge vorhanden sind, dann Funktion verlassen
    Switch @GUI_CtrlId
    Case $idCMAllFiles ; Alle Dateinamen auslesen
    ReDim $aItems[$iItemCount]
    For $i = 0 To $iItemCount - 1
    $aItems[$i] = _GUICtrlListView_GetItemTextString($hFileList, $i)
    Next
    Case $idCMMarkFiles ; nur die markierten Dateinamen auslesen
    $aSelItems = ControlListView($hGui, '', $idFileList, 'GetSelected', 1) ; markierte Items auslesen
    If $aSelItems = '' Then Return ; wenn keine Einträge markiert sind, dann Funktion verlassen
    $aSelItems = StringSplit($aSelItems, '|', 2) ; ansonsten Array mit Indizes erstellen
    ReDim $aItems[UBound($aSelItems)] ; das Array entsprechend dimensionieren
    For $i = 0 To UBound($aSelItems) - 1
    $aItems[$i] = _GUICtrlListView_GetItemTextString($hFileList, $aSelItems[$i])
    Next
    EndSwitch
    $sDefaultFilename = StringFormat('Ergebnis der Suche (%s%s%s %s%s%s).txt', @YEAR, @MON, @MDAY, @HOUR, @MIN, @SEC) ; Default-Dateinamen erstellen
    $sSaveFile = FileSaveDialog($sTitle & ' - Ergebnis der Suche speichern...', '', 'Textdateien (*.txt)', 18, $sDefaultFilename, $hGui) ; Benutzer nach Speicherort und Dateinamen fragen
    If @error Then Return ; wenn dieser auf [Abbrechen] geklickt hat, dann die Funktion verlassen
    $hFile = FileOpen($sSaveFile, 2) ; ausgewählte Datei zum speichern öffnen
    If $hFile = -1 Then ; wenn ein Fehler aufgetreten ist, dann den Benutzer informieren
    _GUICtrlStatusBar_SetIcon($hStatus, 0, $hAttentionIcon)
    _GUICtrlStatusBar_SetText($hStatus, 'Datei konnte nicht gespeichert werden!', 0)
    Else ; ansonsten die Einträge in die Datei speichern
    For $i = 0 To UBound($aItems) - 1
    FileWrite($hFile, StringRegExpReplace($aItems[$i], '(.+)\|(.+)\|(.+)\|(.+)\|(.+)\|(.+)\|(.+)', '"$7$1.$2"' & @CRLF & '$4' & @TAB & '$5 $6 $3' & @CRLF & @CRLF))
    Next
    FileClose($hFile) ; Datei schließen
    _GUICtrlStatusBar_SetIcon($hStatus, 0, $hInfoIcon) ; und Benutzer informieren
    _GUICtrlStatusBar_SetText($hStatus, 'Datei gespeichert!', 0)
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _SortFileList()
    Local $iItemCount = _GUICtrlListView_GetItemCount($hFileList), $iColumnCount = _GUICtrlListView_GetColumnCount($hFileList)
    If $iItemCount = 0 Then Return
    Local $aList = $aFileList ; lokale Kopie des ListView-Arrays erstellen
    Local $iSortColumn = GUICtrlGetState($idFileList), $iDescending = 0
    Local $hFileListHeader = _GUICtrlListView_GetHeader($hFileList)
    Local $iItemFlags = _GUICtrlHeader_GetItemFlags($hFileListHeader, $iSortColumn) ; Flags auslesen (Pfeil nach oben/unten)
    GUISetState(@SW_LOCK, $hGui)
    For $i = 0 To $iColumnCount - 1
    _GUICtrlHeader_SetItemFlags($hFileListHeader, $i, 0)
    Next
    If BitAND($iItemFlags, 8) Then ; wenn Pfeil nach oben, dann Sortierrichtung umkehren
    $iDescending = 1
    _GUICtrlHeader_SetItemFlags($hFileListHeader, $iSortColumn, 4) ; Pfeil nach unten setzen
    Else
    _GUICtrlHeader_SetItemFlags($hFileListHeader, $iSortColumn, 8) ; Pfeil nach oben setzen
    EndIf
    ToolTip('Die Liste wird sortiert!' & @CR & 'Bitte warten...', Default, Default, $sTitle, 1, 1)
    _ArraySort($aList, $iDescending, 0, 0, $iSortColumn) ; lokale Kopie sortieren
    For $i = 0 To $iItemCount - 1
    $aList[$i][2] = _StringAddThousandsSep($aList[$i][2]) ; Tausender-Punkte wieder setzen
    $aList[$i][4] = StringRegExpReplace($aList[$i][4], '(\d{4})\.(\d{2})\.(\d{2}) (.+)', '$3.$2.$1 $4') ; Datum wieder nach TT.MM.YYYY
    $aList[$i][5] = StringRegExpReplace($aList[$i][5], '(\d{4})\.(\d{2})\.(\d{2}) (.+)', '$3.$2.$1 $4') ; Datum wieder nach TT.MM.YYYY
    Next
    _GUICtrlListView_DeleteAllItems($hFileList)
    _GUICtrlListView_AddArray($hFileList, $aList)
    ToolTip('')
    GUISetState(@SW_UNLOCK, $hGui)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _ReadListView2Array()
    Local $iItemCount = _GUICtrlListView_GetItemCount($hFileList), $iColumnCount = _GUICtrlListView_GetColumnCount($hFileList)
    If $iItemCount = 0 Then Return
    ReDim $aFileList[$iItemCount][$iColumnCount]
    For $i = 0 To $iItemCount - 1
    For $j = 0 To $iColumnCount - 1
    Switch $j
    Case 2
    $aFileList[$i][$j] = Number(StringReplace(_GUICtrlListView_GetItemText($hFileList, $i, $j), '.', '')) ; Tausender-Punkte entfernen (wird sonst falsch sortiert)
    Case 4, 5
    $aFileList[$i][$j] = StringRegExpReplace(_GUICtrlListView_GetItemText($hFileList, $i, $j), '(\d{2})\.(\d{2})\.(\d{4}) (.+)', '$3.$2.$1 $4') ; Datum umwandeln nach YYYY.MM.TT
    Case Else
    $aFileList[$i][$j] = _GUICtrlListView_GetItemText($hFileList, $i, $j)
    EndSwitch
    Next
    Next
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetSearchExt()
    $sSearchExt = $aSearchExt[_GUICtrlComboBox_GetCurSel($idSearchExt)]
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $tNMHDR, $hWndFrom, $tInfo, $iIndex, $sDir, $sFile
    Local Const $tagNMITEMACTIVATE64 = "hwnd hWndFrom;uint_ptr IDFrom;INT_ptr Code;int Index;int SubItem;int NewState;int OldState;" & _
    "int Changed;int X;int Y;int lParam;int KeyFlags" ; als Alternative für 64 Bit Support, Danke progandy!
    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, 'hWndFrom'))
    Switch $hWndFrom
    Case $hFileList
    Switch DllStructGetData($tNMHDR, 'Code')
    Case $NM_DBLCLK
    $tInfo = DllStructCreate($tagNMITEMACTIVATE64, $ilParam)
    $iIndex = DllStructGetData($tInfo, 'Index')
    If $iIndex > -1 Then
    $sDir = _GUICtrlListView_GetItemText($hFileList, $iIndex, 6)
    $sFile = _GUICtrlListView_GetItemText($hFileList, $iIndex, 0) & '.' & _GUICtrlListView_GetItemText($hFileList, $iIndex, 1)
    ShellExecute($sDir & $sFile, '', $sDir)
    EndIf
    EndSwitch
    EndSwitch
    $tNMHDR = ''
    $tInfo = ''
    Return $GUI_RUNDEFMSG
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _SelectSearchDir()
    Local $sPath = FileSelectFolder('Bitte das Suchverzeichnis auswählen!' & @CR & 'Dieses Verzeichnis wird dann rekursiv durchsucht.', '', 2, '', $hGui)
    If FileExists($sPath) Then
    GUICtrlSetData($idSetSearchDir, $sPath)
    GUICtrlSetState($idSetDrive, $GUI_UNCHECKED)
    GUICtrlSetState($idSetDir, $GUI_CHECKED)
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _Search()
    Local $sSearchword = GUICtrlRead($idSearchString), $sPath = ''
    If $sSearchword = '' Then $sSearchword = '*'
    If Not BitAND(GUICtrlRead($idSetRegEx), $GUI_CHECKED) Then
    $sSearchword = StringRegExpReplace($sSearchword, '[\\:/{}()\[\]]', '')
    $sSearchword = StringReplace($sSearchword, '.', '\.')
    $sSearchword = StringReplace($sSearchword, '*', '.*')
    $sSearchword = StringReplace($sSearchword, '?', '.')
    $sSearchword = '\A' & $sSearchword & $sSearchExt & '\z'
    EndIf
    If Not BitAND(GUICtrlRead($idSetCaseSensitiv), $GUI_CHECKED) Then $sSearchword = '(?i)' & $sSearchword
    _GUICtrlListView_DeleteAllItems($hFileList)
    If Not BitAND(GUICtrlRead($idSetView), $GUI_CHECKED) Then
    _GUICtrlListView_BeginUpdate($hFileList)
    GUICtrlSetState($idFileList, $GUI_DISABLE)
    EndIf
    ;~ ConsoleWrite('Suchbegriff: ' & $sSearchword & @CR)
    $iFoundCount = 0
    $iAllFiles = 0
    $iSearchTimer = TimerInit()
    If BitAND(GUICtrlRead($idSetDrive), $GUI_CHECKED) Then ; Wenn Laufwerkssuche ausgewählt
    For $i = 0 To UBound($aidDrives) - 1
    If Not $fStartSearch Then ExitLoop
    If BitAND(GUICtrlRead($aidDrives[$i]), $GUI_CHECKED) Then ; Laufwerk angehakt?
    If DriveStatus(GUICtrlRead($aidDrives[$i], 1)) = 'READY' Then ; Laufwerk ist bereit (Datenträger vorhanden)?
    $sPath = GUICtrlRead($aidDrives[$i], 1)
    Local $hDll = DllOpen('kernel32.dll')
    _SearchRekursive($sPath, $sSearchword, $hDll)
    DllClose($hDll)
    EndIf
    EndIf
    Next
    Else ; Verzeichnissuche ausgewählt
    $sPath = GUICtrlRead($idSetSearchDir)
    Local $hDll = DllOpen('kernel32.dll')
    _SearchRekursive($sPath, $sSearchword, $hDll)
    DllClose($hDll)
    EndIf
    If Not BitAND(GUICtrlRead($idSetView), $GUI_CHECKED) Then
    _GUICtrlListView_EndUpdate($hFileList)
    GUICtrlSetState($idFileList, $GUI_ENABLE)
    EndIf
    _CancelSearch()
    Sleep(250)
    _ReadListView2Array()
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _SearchRekursive($sPath, $sSearchword, $hDll)
    If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
    Local Static $iTimer = TimerInit()
    Local $hSearch = FileFindFirstFile($sPath & '*'), $sFile = '', $aFileAtt, $iIndex = 0, $iNewFound = 0
    If $hSearch <> -1 Then
    While 1
    $sFile = FileFindNextFile($hSearch)
    If @error Then ExitLoop ; wenn ein Fehler (kein weiteres Verzeichnis und/oder Datei vorhanden) aufgetreten ist, die Suchschleife verlassen
    If @extended Then ; $sFile ist ein Verzeichnis
    If Not $fStartSearch Then ExitLoop ; Wenn Benutzer auf Stop geklickt hat, Suchschleife verlassen
    $aFileAtt = DllCall($hDll, 'dword', 'GetFileAttributesW', 'wstr', $sPath & $sFile) ; Attribute auslesen
    If @error Or BitAND($aFileAtt[0], $FILE_ATTRIBUTE_REPARSE_POINT) Then ContinueLoop ; Wenn NTFS-ReparsePoint, dann weitersuchen.
    If Not BitAND(GUICtrlRead($idSetHiddenView), $GUI_CHECKED) Then
    If BitAND($aFileAtt[0], $FILE_ATTRIBUTE_SYSTEM) Or BitAND($aFileAtt[0], $FILE_ATTRIBUTE_HIDDEN) Then ContinueLoop ; Wenn versteckte oder Systemdatei, dann weitersuchen.
    EndIf
    _SearchRekursive($sPath & $sFile, $sSearchword, $hDll) ; sonst ins Unterverzeichnis wechseln (rekursiv)
    Else ; $sFile ist eine Datei
    If Not $fStartSearch Then ExitLoop ; Wenn Benutzer auf Stop geklickt hat, Suchschleife verlassen
    If Not BitAND(GUICtrlRead($idSetHiddenView), $GUI_CHECKED) Then
    $aFileAtt = DllCall($hDll, 'dword', 'GetFileAttributesW', 'wstr', $sPath & $sFile) ; Attribute auslesen
    If @error Or BitAND($aFileAtt[0], $FILE_ATTRIBUTE_SYSTEM) Or BitAND($aFileAtt[0], $FILE_ATTRIBUTE_HIDDEN) Then ContinueLoop ; Wenn versteckte oder Systemdatei, dann weitersuchen.
    EndIf
    $iAllFiles += 1
    If StringRegExp($sFile, $sSearchword) Then ; Wenn das Suchwort im Dateinamen enthalten ist, dann neuen Listview-Eintrag erzeugen.
    If StringInStr($sFile, '.') Then ; Punkt im Dateinamen vorhanden, dann trennen nach Dateiname|Erweiterung
    $iIndex = _GUICtrlListView_AddItem($hFileList, StringRegExpReplace($sFile, '(.+)\..+', '$1'), 0, _GUICtrlListView_GetItemCount($hFileList) + 9999)
    _GUICtrlListView_AddSubItem($hFileList, $iIndex, StringRegExpReplace($sFile, '.+\.(.+)', '$1'), 1)
    Else ; ansonsten nur den Dateinamen übernehmen und Erweiterung leer lassen
    $iIndex = _GUICtrlListView_AddItem($hFileList, $sFile)
    EndIf
    _GUICtrlListView_AddSubItem($hFileList, $iIndex, _StringAddThousandsSep(FileGetSize($sPath & $sFile)), 2) ; Dateigröße hinzufügen
    _GUICtrlListView_AddSubItem($hFileList, $iIndex, FileGetAttrib($sPath & $sFile), 3) ; Dateiattribute hinzufügen
    _GUICtrlListView_AddSubItem($hFileList, $iIndex, StringRegExpReplace(FileGetTime($sPath & $sFile, 0, 1), '(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})', '$3.$2.$1 $4:$5:$6'), 4) ; Erstellungsdatum hinzufügen
    _GUICtrlListView_AddSubItem($hFileList, $iIndex, StringRegExpReplace(FileGetTime($sPath & $sFile, 1, 1), '(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})', '$3.$2.$1 $4:$5:$6'), 5) ; Änderungsdatum hinzufügen
    _GUICtrlListView_AddSubItem($hFileList, $iIndex, $sPath, 6) ; Verzeichnis hinzufügen
    $iFoundCount += 1
    EndIf
    EndIf
    If TimerDiff($iTimer) > 250 Then ; Die Meldungen in der Statuszeile nur alle 250ms aktualisieren (erhöht die Suchgeschwindigkeit)
    $iTimer = TimerInit()
    _GUICtrlStatusBar_SetText($hStatus, 'Suche läuft... (' & _StringAddThousandsSep($iFoundCount) & ' Treffer)', 0)
    _GUICtrlStatusBar_SetText($hStatus, $sPath, 1)
    _GUICtrlStatusBar_SetText($hStatus, _StringAddThousandsSep($iAllFiles) & ' Dateien', 2)
    If $iFoundCount <> $iNewFound Then
    $iNewFound = $iFoundCount
    _GUICtrlListView_SetColumnWidth($idFileList, 0, $LVSCW_AUTOSIZE)
    _GUICtrlListView_SetColumnWidth($idFileList, 6, $LVSCW_AUTOSIZE)
    EndIf
    EndIf
    WEnd
    EndIf
    FileClose($hSearch)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _StartSearch()
    $fStartSearch = True
    GUICtrlSetState($idSearchString, $GUI_DISABLE)
    GUICtrlSetState($idSearchExt, $GUI_DISABLE)
    _GUICtrlStatusBar_SetIcon($hStatus, 0, $hSearchIcon)
    _GUICtrlStatusBar_SetText($hStatus, 'Suche...', 0)
    GUICtrlSetData($idSearchStart, 'Stop')
    GUICtrlSetOnEvent($idSearchStart, '_CancelSearch')
    GUICtrlSetImage($idSearchStart, 'shell32.dll', -110, 1)
    GUISetCursor(1, 1, $hGui)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _CancelSearch()
    $fStartSearch = False
    GUICtrlSetState($idSearchExt, $GUI_ENABLE)
    GUICtrlSetState($idSearchString, $GUI_ENABLE)
    _GUICtrlStatusBar_SetIcon($hStatus, 0, $hInfoIcon)
    _GUICtrlStatusBar_SetText($hStatus, 'Bereit.', 0)
    _GUICtrlStatusBar_SetText($hStatus, _StringAddThousandsSep($iFoundCount) & ' Treffer. Benötigte Zeit: ' & _TicksToTimeFormat(TimerDiff($iSearchTimer), '%hh:%mm:%ss.%ms'), 1)
    _GUICtrlStatusBar_SetText($hStatus, _StringAddThousandsSep($iAllFiles) & ' Dateien', 2)
    GUICtrlSetData($idSearchStart, 'Start')
    GUICtrlSetOnEvent($idSearchStart, '_StartSearch')
    GUICtrlSetImage($idSearchStart, 'shell32.dll', -23, 1)
    GUISetCursor(2, 0, $hGui)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _CloseGui()
    _GUICtrlListView_UnRegisterSortCallBack($hFileList)
    _WinAPI_DestroyIcon($hInfoIcon)
    _WinAPI_DestroyIcon($hDiskIcon)
    _WinAPI_DestroyIcon($hSearchIcon)
    _WinAPI_DestroyIcon($hAttentionIcon)
    GUIDelete($hGui)
    Exit
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _CreateDrives()
    If IsArray($aidDrives) Then
    For $i = UBound($aidDrives) To 0 Step -1
    GUICtrlDelete($aidDrives[$i])
    Next
    EndIf
    Local $aDrives = DriveGetDrive('ALL'), $iCount = 0
    Global $aidDrives[$aDrives[0]]
    For $i = 1 To $aDrives[0]
    Switch DriveStatus($aDrives[$i])
    Case 'READY', 'NOTREADY'
    $aidDrives[$iCount] = GUICtrlCreateCheckbox(StringUpper($aDrives[$i]), 410 + Mod($iCount, 13) * 44, 24 + Int($iCount / 13) * 22, 36, 22)
    GUICtrlSetFont(-1, 11, 400, 0, 'Arial')
    GUICtrlSetTip(-1, 'Hier können die Laufwerke ausgewählt werden, die durchsucht werden sollen.' & @CR & 'Standardmäßig sind alle Festplatten ausgewählt.', '', 1, 1)
    $iCount += 1
    EndSwitch
    Next
    _SetDriveCheckbox()
    ReDim $aidDrives[$iCount]
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _SetDriveCheckbox($sState = $GUI_CHECKED, $sType = 'Fixed')
    For $i = 0 To UBound($aidDrives) - 1
    If $sType = 'ALL' Or (DriveGetType(GUICtrlRead($aidDrives[$i], 1)) = $sType) Then GUICtrlSetState($aidDrives[$i], $sState)
    Next
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _ChangeSearchPath()
    If BitAND(GUICtrlRead($idSetDrive), $GUI_CHECKED) Then ; Laufwerke als Suchpfad ausgewählt
    _SetDriveCheckbox($GUI_ENABLE, 'ALL')
    GUICtrlSetBkColor($idSetSearchDir, 0xCCCCCC)
    GUICtrlSetState($idSetSearchDir, $GUI_DISABLE)
    GUICtrlSetState($idGetSearchDir, $GUI_DISABLE)
    Else ; Verzeichnis als Suchpfad
    GUICtrlSetBkColor($idSetSearchDir, 0xEEEEEE)
    GUICtrlSetState($idSetSearchDir, $GUI_ENABLE)
    GUICtrlSetState($idGetSearchDir, $GUI_ENABLE)
    _SetDriveCheckbox($GUI_DISABLE, 'ALL')
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ; Function Name: _TicksToTimeFormat($iTicks, $sFormat = '%hh:%mm:%ss')
    ; Description:: Diese Funktion wandelt Millisekunden in ein anzugebenes Zeitformat um
    ; Parameter(s): $iTicks = Zeit in Millisekunden
    ; $sFormat:
    ; %ww für Wochen
    ; %dd für Tage
    ; %hh für Stunden
    ; %mm für Minuten
    ; %ss für Sekunden
    ; %ms für Millisekunden
    ; sonstige Zeichen, die dazwischen stehen, werden übernommen
    ; Requirement(s): -
    ; Return Value(s): Zeit im ausgewählten Format (String)
    ; Author(s): Oscar (http://www.autoit.de)
    ;===============================================================================
    Func _TicksToTimeFormat($iTicks, $sFormat = '%hh:%mm:%ss')
    Local $aTime[6], $sOut, $aTimeFormat[6] = ['ww', 'dd', 'hh', 'mm', 'ss', 'ms'], $aFormat
    $aTime[4] = Int($iTicks / 1000)
    $aTime[5] = $iTicks - $aTime[4] * 1000
    $aTime[0] = Int($aTime[4] / 604800)
    $aTime[4] = Mod($aTime[4], 604800)
    $aTime[1] = Int($aTime[4] / 86400)
    $aTime[4] = Mod($aTime[4], 86400)
    $aTime[2] = Int($aTime[4] / 3600)
    $aTime[4] = Mod($aTime[4], 3600)
    $aTime[3] = Int($aTime[4] / 60)
    $aTime[4] = Mod($aTime[4], 60)
    $aFormat = StringRegExp($sFormat, '(?i)%([^%]+)', 3)
    If Not IsArray($aFormat) Then Return SetError(1, 0, $iTicks)
    For $i = 0 To UBound($aFormat) - 1
    For $j = 0 To UBound($aTimeFormat) - 1
    If StringLeft($aFormat[$i], 2) = $aTimeFormat[$j] Then $sOut &= StringFormat('%0' & 2 + ($j = 5) & 'i', $aTime[$j]) & StringMid($aFormat[$i], 3)
    Next
    Next
    Return $sOut
    EndFunc ;==>_TicksToTimeFormat

    [/autoit] [autoit][/autoit] [autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _StringAddThousandsSep
    ; Description ...: Returns the original numbered string with the Thousands delimiter inserted.
    ; Syntax.........: _StringAddThousandsSep($sString[, $sThousands = -1[, $sDecimal = -1]])
    ; Parameters ....: $sString - The string to be converted.
    ; $sThousands - Optional: The Thousands delimiter
    ; $sDecimal - Optional: The decimal delimiter
    ; Return values .: Success - The string with Thousands delimiter added.
    ; Author ........: SmOke_N (orignal _StringAddComma
    ; Modified.......: Valik (complete re-write, new function name)
    ; Remarks .......:
    ; Related .......:
    ; Link ..........;
    ; Example .......; Yes
    ; ===============================================================================================================================
    Func _StringAddThousandsSep($sString, $sThousands = -1, $sDecimal = -1)
    Local $sResult = "" ; Force string
    Local $rKey = "HKCU\Control Panel\International"
    If $sDecimal = -1 Then $sDecimal = RegRead($rKey, "sDecimal")
    If $sThousands = -1 Then $sThousands = RegRead($rKey, "sThousand")
    Local $aNumber = StringRegExp($sString, "(\D?\d+)\D?(\d*)", 1) ; This one works for negatives.
    If UBound($aNumber) = 2 Then
    Local $sLeft = $aNumber[0]
    While StringLen($sLeft)
    $sResult = $sThousands & StringRight($sLeft, 3) & $sResult
    $sLeft = StringTrimRight($sLeft, 3)
    WEnd
    $sResult = StringTrimLeft($sResult, StringLen($sThousands)) ; Strip leading thousands separator
    If $aNumber[1] <> "" Then $sResult &= $sDecimal & $aNumber[1]
    EndIf
    Return $sResult
    EndFunc ;==>_StringAddThousandsSep

    [/autoit]
  • Hallo Oscar,

    ein gutes Programm, wie ich finde! :thumbup:

    Aber ich habe noch 2 Verbesserungsvorschläge:
    1. Während der Suche kann man noch in den Einstellungen Veränderungen vornehmen. (z.B. Groß- und Kleinschreibung aktivieren)
    2. Vielleicht könnte man die Suche auch auf benutzerdefinierte Dateiendungen beschränken.

    Ansonsten wirklich schön gemacht!

    MfG Xenon :)

  • Hallo,

    ich meinte, dass man die erlaubten Dateiendungen selbst in ein Inputfeld eingeben kann (statt vorgegebener Auswahl).
    Aber stimmt, das kann man ja per regulärem Ausdruck machen, da hab ich nicht dran gedacht... :pinch:

    MfG Xenon :)