Dateisuche mit AutoIt

  • Hi Leute...seit langem mal wieder ein thread von mir o_O

    Folgendes:

    Es muss doch mit AutoIt möglich sein eine datei zu suchen und als Rückgabewert, den Pfad wo die Datei liegt wiederzubekommen.

    Ich dachte da an was wie

    [autoit]

    Filesearch("Gesuchtedatei.exe")

    [/autoit]

    rauskommen müsste dann idealerweise

    [autoit]

    Msgbox(48,"Ergebniss","Die Datei liegt in:
    C:\Windows\System32\wDrdir")

    [/autoit]

    Ich hab das ja schon in der Shoutbox gefragt, aber dort sagte man mir nur das es nur eine umständliche Lösung dafür gebe

    Zitat


    <daniel w.> Rekursives Auslesen der Festplatte und dann gucken welche Datei so heisst

    <Waluev> sry das ich so dumm bin :D aber was soll das jetz genau heissen?

    <huggy> Dass du ALLE daten auf der festplatte in n array haust und das durchsuchst^^ ps: viel spaß und vieeel geduld smile

    <huggy> naja, was GEHT: du kannst dir einbauen, dass es in ne .txt geschrieben wird - und während du in der schule bist oder was weiß der geier, sucht er.

    <huggy> kann man verfeinern durch ne pause/resume funktion

    Ich kann mir aber nicht vorstllen, dass das nur so umständlich geht...deshalb hoffe ich das mir durch den eröffneten thread vlt mehrere Leute helfen können als die zwei..trotzdem danke an sie ;)


    Also wer mir da helfen kan; vielen dank schonmal


    Das wars erstmal:
    Waluev

    Flensburg ist wie Payback - wenn man 18 Punkte hat bekommt man ein Fahrrad.

    Einmal editiert, zuletzt von Waluev (26. Februar 2007 um 15:38)

    • Offizieller Beitrag

    HI,

    Spoiler anzeigen
    [autoit]

    ;This could take a while if you are searching the entire drive
    #include <array.au3>;only using for array display
    $aArray = _ParseAndFind('C:\', 'test.txt');only returning what files were found (not deleting anything)
    _ArrayDisplay($aArray, 'Found')

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

    Func _ParseAndFind($hDirectory, $hFindFile, $iDelete = 0, $iPrompt = 0, $iOverRide = 0)
    RunWait(@Comspec & ' /c dir /b /s /a "' & $hDirectory & '" > "' & _
    @TempDir & '\RecursivOutput.txt"', @WorkingDir, @SW_HIDE)
    If Not FileExists(@TempDir & '\RecursivOutput.txt') Then Return SetError(1, 0, 0)
    Local $hFoundFiles = FileRead(@TempDir & '\RecursivOutput.txt')
    FileDelete(@TempDir & '\RecursivOutput.txt')
    If Not $hFoundFiles Then Return SetError(2, 0, 0)
    Local $sHold = '', $aSplit = StringSplit(StringStripCR($hFoundFiles), @LF)
    For $iCC = 1 To UBound($aSplit) - 1
    If StringTrimLeft($aSplit[$iCC], StringInStr($aSplit[$iCC], '\', 0, -1)) = $hFindFile Then
    If $iPrompt And $iDelete Then
    If MsgBox(36, 'Delete?', 'Would you like to delete:' & @CR & $aSplit[$iCC]) = 6 Then
    If Not FileDelete($aSplit[$iCC]) And $iOverRide And StringInStr(FileGetAttrib($aSplit[$iCC]), 'R') Then
    FileSetAttrib($aSplit[$iCC], '-R')
    If FileDelete($aSplit[$iCC]) Then $sHold &= $aSplit[$iCC] & @LF
    Else
    $sHold &= $aSplit[$iCC] & @LF
    EndIf
    EndIf
    ElseIf $iDelete Then
    If Not FileDelete($aSplit[$iCC]) And $iOverRide And StringInStr(FileGetAttrib($aSplit[$iCC]), 'R') Then
    FileSetAttrib($aSplit[$iCC], '-R')
    If FileDelete($aSplit[$iCC]) Then $sHold &= $aSplit[$iCC] & @LF
    Else
    $sHold &= $aSplit[$iCC] & @LF
    EndIf
    Else
    $sHold &= $aSplit[$iCC] & @LF
    EndIf
    EndIf
    Next
    If $sHold Then Return StringSplit(StringTrimRight($sHold, 1), @LF)
    Return SetError(3, 0, 0)
    EndFunc

    [/autoit]

    So long,

    Mega

  • Hi...

    Thx für die schnellen Antworten.

    ABER:

    Das ist doch seltsam das das nur so kompliziert geht?!

    Wenn ich per Windowssuche was suche dauert das zwar auch EIN BISSCHEN aber nicht so ewig...


    gibts da echt keine andere Lösung?! :(


    Waluev

    Flensburg ist wie Payback - wenn man 18 Punkte hat bekommt man ein Fahrrad.

    • Offizieller Beitrag

    Wenn du mit C++ suchen würdest, wärest du (fast) so schnell wie Windows. Aber AutoIt ist von er Performance her eben langsamer. Und da Microsoft nicht in der Lage war, in > 6 Jahren WinFS, das neue Dateisystem für Vista, fertigzustellen, wird das auch noch eine Weile so bleiben...

    peethebee

  • na was wär denn wenn man das mit C++ programmiert und dann ein Plugin für AI macht...also von der Performance her?!


    Waluev

    Flensburg ist wie Payback - wenn man 18 Punkte hat bekommt man ein Fahrrad.

  • Naja und die Windows-Suche wäre auch um einiges langsamer wenn sie die Dateien nicht indizieren würde.
    Würde man auf eine Datenbank mit den indizierten Dateien zurückgreifen können würde man da auch mit AutoIt schneller suchen können - das wär dann aber tatsächlich zu viel Aufwand.

  • Trotzdem....ich finde es extrem seltsam^^


    Ich mein diese schlauen Kerle, die das entwickelt haben, müssen doch auch ne idee gehabt haben, wie man EINFACH eine Datei suchen kann?!?!?!


    :hammer: :hammer:
    Mich regt das auf^^
    :hammer: :hammer:


    Waluev

    Flensburg ist wie Payback - wenn man 18 Punkte hat bekommt man ein Fahrrad.

  • Das ist die einfache Variante!
    Die Windows-Suche macht das nicht anders.

    Es werden alle Dateien auf der Platte in eine Datenbank geschmissen und wenn eine Suchanfrage gestellt wird, wird diese Datenbank dann daraufhin abgefragt und spuckt den Ordner aus.
    Exakt so wie diese AutoIt-Funktion hier.
    Nur das hier die Datenbank erst noch erstellt wird und nicht schon vorher vorhanden ist.

  • Also ich brauchs für folgendes...


    Bei dem Spiel CS kann man ja eigene Logo machen..jetz soll dieses Prog automatisch eine Datei suchen die es nur in diesem Ordner gibt wo das logo hinkommt ..den Pfad ausspucken und das Logo wird dann automatisch dort hin kopiert.


    waluev

    Flensburg ist wie Payback - wenn man 18 Punkte hat bekommt man ein Fahrrad.

  • Hi,

    wenn du es im Steam Ordner ändern willst dann kannste dir das aus der Registry auslesen:

    Code
    Regpath: HKEY_CURRENT_USER\Software\Valve\Steam
    Keyname: SteamPath
    Keytyp: Reg_SZ

    Mfg

  • Jop genau..

    Thx für den hinweis wegen der registry so könnte es klappen


    Waluev

    Flensburg ist wie Payback - wenn man 18 Punkte hat bekommt man ein Fahrrad.

  • Hab mir nochmal Gedanken gemacht wie man diese FileSearch-Funktion nur allein mit reinen AutoIt-Mitteln doch noch vertretbar schnell realisieren kann.
    Das ist mein Ergebniss - schneller hab ich es bis jetzt noch nicht hinbekommen:

    [autoit]

    ;======================================================================================
    ;Function Name: FileSearch()
    ;Description: Sucht eine Datei in einem Verzeichnis und seinen Unterverzeichnissen
    ;Parameter(s): $recdir: Das Startverzeichnis in dem gesucht werden soll
    ; $Fsrch: Dateiname der zu suchenden Datei
    ;Return Value(s): Erfolg - Gibt den Pfad der Datei zurück
    ; Misserfolg - Gibt einen Nullstring zurück und setzt @error auf 1
    ;Author(s): AspirinJunkie (https://autoit.de/www.German-nLite.de)
    ;=======================================================================================

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

    Func _FileSearch($recdir, $Fsrch)

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

    $recdir = StringRegExpReplace($recdir, "\\ *$", '')

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

    Local $rcstrt, $rcffnf, $rectmpdrs[1000], $rci

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

    $rcstrt = FileFindFirstFile($recdir & '\*')
    If $rcstrt <> - 1 Then
    While 1
    $rcffnf = FileFindNextFile($rcstrt)
    If @error Then ExitLoop
    If StringInStr(FileGetAttrib($recdir & '\' & $rcffnf), "D") Then
    $rectmpdrs[0] += 1
    $rectmpdrs[$rectmpdrs[0]] = $rcffnf
    Else
    If $rcffnf = $Fsrch Then
    Return $recdir & '\' & $rcffnf
    EndIf
    EndIf
    WEnd
    EndIf

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

    FileClose($rcstrt)

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

    If $rectmpdrs[0] > 0 Then
    For $rci = 1 To $rectmpdrs[0]
    $rcpfad = _FileSearch($recdir & '\' & $rectmpdrs[$rci], $Fsrch)
    If Not @error Then
    Return $rcpfad
    EndIf
    Next
    EndIf

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

    SetError(1)
    Return ''
    EndFunc ;==>_FileSearch

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

    ;=======================================================================================

    [/autoit]


    Allerdings mussten zur Optimierung ein paar Kompromisse eingegangen werden:
    Erstens es kann nicht per Wildcards gesucht werden - heißt also es kann nur nach exakt bekannten Dateinamen gesucht werden und außerdem wird nur nach jeweils einer Datei gesucht - eine eventuell 2. Datei mit diesem Namen wird also nicht zurückgegeben.
    Ich denke für diesen speziellen Fall sollte man damit aber noch relativ vertretbare Geschwindigkeiten erzeugen.

    Außerdem habe ich, weil ich gerade dabei war, eine eigene _FileListToArray mit Unterverzeichnissen-Funktion geschrieben.
    Nach meinen Tests ist diese um den Faktor 2 bis 6 schneller als die bisher dazu von mir verwendete _GetFileList()-Funktion von Jos van der Zande.

    Vielleicht braucht es mal einer (den 2. Aufrufparameter unberührt lassen):

    [autoit]

    ;===============================================================================
    ;Function Name: _recfileslst ( $recdir )
    ;Description: Gibt ein Array mit den Dateipfaden aller, innerhalb des
    ; angegebenen Verzeichnis und seinen Unterverzeichnissen
    ; befindlichen, Dateien zurück
    ;Parameter(s): $recdir: Das Startverzeichnis in dem gesucht werden soll
    ;Return Value(s): Erfolg - Gibt ein Array mit den gefundenen Dateien zurück
    ; Misserfolg - setzt @error auf 1
    ;Author(s): AspirinJunkie (https://autoit.de/www.German-nLite.de)
    ;===============================================================================

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

    Func _recfileslst($recdir, $rcend = 1)

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

    $recdir = StringRegExpReplace($recdir, "\\ *$", '')
    Local $rcstrt, $rcffnf, $rectmpdrs, $rci

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

    If $rcend Then
    Global $rcfls[200000]
    $rcfls[0] = 0
    EndIf

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

    Local $rectmpdrs[1000]

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

    $rectmpdrs[0] = 0

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

    $rcstrt = FileFindFirstFile($recdir & '\*')
    If $rcstrt <> - 1 Then
    While 1
    $rcffnf = FileFindNextFile($rcstrt)
    If @error Then ExitLoop

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

    If StringInStr(FileGetAttrib($recdir & '\' & $rcffnf), "D") Then
    $rectmpdrs[0] += 1
    $rectmpdrs[$rectmpdrs[0]] = $rcffnf
    Else
    $rcfls[0] += 1
    $rcfls[$rcfls[0]] = $recdir & '\' & $rcffnf
    EndIf
    WEnd
    EndIf

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

    FileClose($rcstrt)

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

    If $rectmpdrs[0] > 0 Then
    For $rci = 1 To $rectmpdrs[0]
    _recfileslst($recdir & '\' & $rectmpdrs[$rci], 0)
    Next
    EndIf

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

    If $rcend Then
    ReDim $rcfls[$rcfls[0] + 1]
    EndIf

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

    If $rcfls[0] = 0 Then
    SetError(1)
    EndIf

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

    Return $rcfls
    EndFunc ;==>_recfileslst

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

    ;===============================================================================

    [/autoit]
  • Denke mal du meinst sowas:

    [autoit]

    ;===============================================================================
    ;Function Name: _recfileslst ( $recdir, $Fsrch )
    ;Description: Gibt ein Array mit den Dateipfaden aller, innerhalb des
    ; angegebenen Verzeichnis und seinen Unterverzeichnissen
    ; befindlichen, Dateien, welche der angegebenen Form
    ; entsprechen zurück.
    ;Parameter(s): $recdir: Das Startverzeichnis in dem gesucht werden soll
    ; $Fsrch = FileMaske mit Wildcard-Unterstützung
    ;Return Value(s): Erfolg - Gibt ein Array mit den gefundenen Dateien zurück
    ; Misserfolg - setzt @error auf 1
    ;Author(s): AspirinJunkie (https://autoit.de/www.German-nLite.de)
    ;===============================================================================

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

    Func _recfileslst($recdir, $Fsrch = '*.*', $rcend = 1)

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

    $recdir = StringRegExpReplace($recdir, "\\ *$", '')
    Local $rcstrt, $rcffnf, $rectmpdrs, $rci, $recdirobj, $recdirpth, $recdirsmlng, $recdirec

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

    If $rcend Then
    Global $rcfls[200000]
    $rcfls[0] = 0
    EndIf

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

    If Not FileExists($recdir) Then
    SetError(1)
    Dim $rcfls[1]
    Return $rcfls
    EndIf

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

    $rcstrt = FileFindFirstFile($recdir & '\' & $Fsrch)
    If $rcstrt <> - 1 Then
    While 1
    $rcffnf = FileFindNextFile($rcstrt)
    If @error Then ExitLoop
    $rcfls[0] += 1
    $rcfls[$rcfls[0]] = $recdir & '\' & $rcffnf
    WEnd
    EndIf

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

    FileClose($rcstrt)

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

    $recdirobj = ObjCreate('Scripting.FileSystemObject')
    If Not @error Then
    $recdirpth = $recdirobj.GetFolder ($recdir & '\')
    $recdirsmlng = $recdirpth.SubFolders
    For $recdirec In $recdirsmlng
    _recfileslst($recdir & '\' & $recdirec.Name, $Fsrch, 0)
    Next
    EndIf

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

    If $rcend Then
    ReDim $rcfls[$rcfls[0] + 1]
    EndIf

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

    If $rcfls[0] = 0 Then
    SetError(1)
    EndIf

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

    Return $rcfls
    EndFunc ;==>_recfileslst

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

    ;===============================================================================

    [/autoit]

    Damit fällt dann auch die FileSearch-Funktion weg da du hier mit dieser Funktion auch suchen kannst.

    Die Funktion ist übrigens auch so immernoch deutlich schneller als die GetFileList-Funktion :party3:

  • Genau das meinte ich, Danke :kiss:

    Edit: Ähmm, ich habe gerade festgestellt, dass deine Version im Gegensatz zur Version von "jos van der Zande" nicht nur Filenamen, sondern auch Ordnernamen berücksichtigt, das kann natürlich manchmal sogar gewünscht sein...
    (d.h. auch, dass du eine Abfrage weniger in deiner Funktion hast ;) )

    Einmal editiert, zuletzt von milko (4. März 2007 um 23:42)