Datei in einem "Unbekannten Ordner" löschen

  • Hallo,
    ich bin mit meinem script fast fertig, jetzt hätte ich gerne noch etwas, unzwar sollte er eine Datei in einem unbekannten ordner löschen,
    zb. Datei ist in "C:\mcgangster\mc\gangster\mcgangster.exe", das wissen wir nicht, er soll lediglich die mcgangster.exe finden und löschen.
    mfg

  • Um eine bestimmte Datei zu löschen brauchst du auch einen vollständigen Pfad, also musst du nach der Datei suchen und sicherstellen, dass sie nur einmalig vorhanden ist.
    Hier ein Beispiel mit meiner Funktion (es gibt aber bestimmt bessere/schnellere).

    Spoiler anzeigen
    [autoit]

    #include <File.au3>
    #include <Array.au3>

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

    $sPath = "C:\mcgangster\mc" ;Pfad in dem gesucht werden soll
    $sFileName = "mcgangster.exe" ;Name der gesuchten Datei

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

    $aFiles = _FileListToArrayRecursiv($sPath, $sFileName, 1)
    _ArrayDisplay($aFiles)

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

    ; #FUNCTION# ======================================================================================
    ; Name ..........: _FileListToArrayRecursiv()
    ; Description ...: Findet Dateien in einem Verzeichnis und allen Unterverzeichnissen
    ; Syntax ........: _FileListToArrayRecursiv($sPath, [$sFilter = "*"])
    ; Parameters ....: $sPath - Verzeichnispfad in dem gesucht werden soll.
    ; $sFilter - [optional] Dateinamenfilter (z.B. "*.mp3"). Wildcards werden unterstützt.
    ; $iFlag - [optional] 0 = Dateien und Ordner auflisten.
    ; 1 = Nur Dateien auflisten.
    ; 2 = Nur Ordner auflisten.
    ; Return values .: Success - Return Array with Files ($Array[0] = Count)
    ; Failure - Return 0
    ; Author ........: name22 (autoit.de)
    ; Remarks .......: Benötigt #include <File.au3>
    ; =================================================================================================
    Func _FileListToArrayRecursiv($sPath, $sFilter = "*", $iFlag = 0)
    Local $aFiles = _FileListToArray($sPath, $sFilter, $iFlag)
    If Not IsArray($aFiles) Then
    Local $aFiles[1]
    $aFiles[0] = 0
    EndIf

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

    Local $aFolders = _FileListToArray($sPath, "*", 2)
    If Not IsArray($aFolders) Then
    If $aFiles[0] = 0 Then Return 0
    Else
    $bResult = False
    For $i = 1 To $aFolders[0]
    $aSearchTmp = _FileListToArrayRecursiv($sPath & "\" & $aFolders[$i], $sFilter, $iFlag)
    If IsArray($aSearchTmp) Then
    $bResult = True
    ReDim $aFiles[$aFiles[0] + $aSearchTmp[0] + 1]
    For $j = 1 To $aSearchTmp[0]
    $aFiles[$aFiles[0] + $j] = $aFolders[$i] & "\" & $aSearchTmp[$j]
    Next
    $aFiles[0] += $aSearchTmp[0]
    EndIf
    Next
    EndIf

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

    Return $aFiles
    EndFunc

    [/autoit]


    MatthiasG. hat Recht, also musst du versuchen die Suche einzugrenzen...

  • ja, soweit ich weis geht es auch mit

    [autoit]

    findfilefirstfile

    [/autoit]

    um es zu suchen
    und dann eben irgentwie file delete,
    es muss doch gehen das der das sucht und löscht/ersetzt?
    mfg und thx

  • Zitat

    ja, soweit ich weis geht es auch mit findfilefirstfile


    Das macht keinen Unterschied, die Funktion wird auch von _FileListToArray verwendet ;). Außerdem heißt es

    [autoit]

    FileFindFirstFile

    [/autoit]
    Zitat

    es muss doch gehen das der das sucht und löscht/ersetzt?


    Wo liegt denn das Problem mit meinem Script? Ist es zu langsam? Denn funktionieren sollte es schon...

  • Generell gibt es Support nur hier im Forum, damit auch andere davon profitieren.

    Würdest du dein Problem beschreiben - denn Lösungsansätze hast du reichlich erhalten - dann findet sich auch sicher jemand, der die weiter helfen kann...

    Gruß,
    Matthias

  • ICQ-Anfragen gehen am Sinn eines Forums ziemlich stark vorbei.
    So kann keiner bereits gelöste Probleme finden und für sich selbst lösen.

    Am einfachsten, schnellsten und kürzesten wäre in dem Fall mal eine Batch-Datei statt einem AutoIt-Skript:

    Code
    for /f %%x IN ('dir /b /s /A:-D "TestTestTest.txt"') do call del %%x
  • kenne das batch teil garnicht, kannst du mir deswegen machen das der eben alle laufwerke durchsucht nach der datei "BEISPIELDATEI.EXE"
    mfg und danke

  • hab mal gegoogelt, finde zwar sachen, aber traue mich nicht die zu benutzen, weil ich das net kenne, kann mir jemand helfen?

  • Hi!

    Funktioniert nicht auf der Windows Partition = REPARSE_POINT

    Spoiler anzeigen
    [autoit]

    Func _WinAPI_SearchTreeForFile($RootPath, $InputPathName, $OutputPathBuffer = 255)
    Dim $aResult = DllCall('imagehlp.dll', 'bool', 'SearchTreeForFile', 'str', $RootPath, 'str', $InputPathName, 'str', $OutputPathBuffer)
    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[3]
    EndFunc ;==>_WinAPI_SearchTreeForFile

    [/autoit]

    o.

    Spoiler anzeigen
    [autoit]

    ;===================================================================================================================================#
    ;Function Name....: _FileListToRekursiv($Pfad, $Wildc = '*', $Flag = 0, $TB = 0, $Mehr = 0)
    ;Description......: Auflistung von Dateien
    ;$Pfad............: Pfad
    ;$Wildc...........: '*' (Standart) Suchbegrif u. o. Wildcards bei Wildcards mit o. suchbegriff $_Flag_ auf '3' setzen es ist auch
    ; möglich mehrere suchbegriffe zu suchen z.B (*wma,*mp3,*txt) o. (wma,mp3,txt) getrennt mit ','
    ;$Flag............: '0' (Standart) Datein u. Ordner '1' nur Datein '2' nur Ordner '3' um mit suchbegriffen zu suchen wie (*.txt)
    ;$TB..............: '0' (Standart) für alle Unter-Verzeichnisse
    ;$Mehr............: '0' (Standart) Ein duchlauf dann wird $RAS gelöscht : '1' Ein Speicher für wiederholten aufruf.
    ;Return Value(s)..: Array mit den gefundenen Dateien u. o Ordner Array[0] endhält die anzahl (Fund)
    ;Author(s)........: Kleiner (http://www.autoit.de) # 21.12.2010 00:00 #
    ;====================================================================================================================================#
    Global Static $K32 = DllOpen('Kernel32.dll')
    Global $F
    Global $FN
    Global $FL
    Global $RP
    Global $RAS
    Global $Expan
    Global Const $IHV = -1
    Global Const $Wstr = 'wstr'
    Global Const $Dword = 'dword'
    Global Const $REPARSE_POINT = 0x400
    Global Const $sDelim = '\', $sDelim1 = '|', $sW = '*'
    Global Const $GetFileAttributesW = 'GetFileAttributesW'

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

    Func _FileListToRekursiv($Pfad, Const $Wildc = '*', Const $Flag = 0, Const $TB = 0, Const $Mehr = 0)
    If Not $Mehr Then $RAS = ''
    $Pfad = StringRegExpReplace($Pfad, '[\\/]+\z', $sDelim) & $sDelim
    If Not FileExists($Pfad) Then Return SetError(1, 0, '')
    If StringRegExp($Wildc, '[\\/:><\|]|(?s)\A\s*\z') Then Return SetError(2, 0, '')
    If Not ($Flag = 0 Or $Flag = 1 Or $Flag = 2 Or $Flag = 3) Then Return SetError(3, 0, '')
    ToRekursiv($Pfad, StringReplace(StringReplace($Wildc, $sW, ''), ',', '$' & $sDelim1) & '$', $Flag, $TB, $Pfad)
    If Not $RAS Then Return SetError(4, 0, '')
    Return StringSplit(StringTrimLeft($RAS, 1), $sDelim1, 2)
    EndFunc ;==>_FileListToRekursiv

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

    Func ToRekursiv($Pfad, $Wildc, $Flag, $TB, $ConstPfad)
    $FL = ''
    If StringInStr($Pfad, $sDelim, 0, $TB, StringLen($ConstPfad) + 1) Then Return True
    $F = FileFindFirstFile($Pfad & $sW)
    If ($F <> $IHV) Then
    Do
    $FN = FileFindNextFile($F)
    If @error Then ExitLoop
    $Expan = @extended
    Switch $Flag
    Case 0
    $RAS &= $sDelim1 & $Pfad & $FN
    If $Expan Then $FL &= $sDelim1 & $Pfad & $FN & $sDelim
    Case 1
    Switch $Expan
    Case 0
    $RAS &= $sDelim1 & $Pfad & $FN
    Case 1
    $FL &= $sDelim1 & $Pfad & $FN & $sDelim
    EndSwitch
    Case 2
    If Not $Expan Then ContinueLoop
    $RAS &= $sDelim1 & $Pfad & $FN
    $FL &= $sDelim1 & $Pfad & $FN & $sDelim
    Case 3
    If $Expan Then $FL &= $sDelim1 & $Pfad & $FN & $sDelim
    If StringRegExp($FN, $Wildc) Then $RAS &= $sDelim1 & $Pfad & $FN
    EndSwitch
    Until False
    EndIf
    FileClose($F)
    If Not $FL Then Return True
    For $For In StringSplit(StringTrimLeft($FL, 1), $sDelim1, 2)
    $RP = DllCall($K32, $Dword, $GetFileAttributesW, $Wstr, $For)
    If @error Then Return True
    If Not BitAND($RP[0], $REPARSE_POINT) Then ToRekursiv($For, $Wildc, $Flag, $TB, $ConstPfad)
    Next
    EndFunc ;==>ToRekursiv

    [/autoit]

    Lg Kleiner

  • Alle Laufwerke per Batch durchsuchen und die Datei löschen wär z.B. so möglich:

    Spoiler anzeigen
  • ah, muss ich dann in eine *.bat reinmachen? und wie starte ich die per autoit script? ersetzt er die datei dann auch durch eine?

  • Ja das ist eine .bat Datei.
    Die brauchst du nicht mit AutoIt aufzurufen sondern kannst sie einfach aus dem Explorer heraus aufrufen.
    Batch-Dateien werden aus AutoIt ansonsten am einfachsten per Shellexecute() geöffnet.

    Wenn es wirklich direkt in AutoIt sein muss dann z.B. so (nur eine msgbox implementiert - das FileDelete kannst du dir ja selbst reinschreiben):

    Dateisuche auf allen Laufwerken
    [autoit]

    Global Const $sDateiname = "TestTestTest.txt"
    Global $aFunde

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

    ;ermittle alle vergebenen Laufwerksbuchstaben:
    $aDrives = DriveGetDrive("all")

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

    ; Gehe alle Laufwerksbuchstaben durch:
    For $i = 1 To $aDrives[0]
    ; suche im derzeitigen Laufwerk nach der Datei und lass alle Funde in ein Array zurückgeben
    $aFunde = FileListCmd($aDrives[$i] & '\', $sDateiname, 1)
    If @error Then ContinueLoop

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

    ; Gehe alle Dateifunde auf dem Laufwerk durch:
    For $Fund In $aFunde
    ; Gibt den gefundenen Dateinamen in einer Messagebox aus:
    MsgBox(0, "Dateiort", $Fund)
    Next
    Next

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

    ;===============================================================================
    ; Name: FileListCmd
    ; Description: Listet Dateien und Ordner in allen Ebenen auf
    ; Parameter(s): $sStPath = Startpfad
    ; $sPat = Pattern mit WildCards * und ?
    ; $iFlag:
    ; 0: Dateien+Ordner
    ; 1: nur Dateien
    ; 2: nur Ordner
    ; $iSplitFlag: regelt wie bei StringSplit die Rückgabe
    ; Requirement(s): keine
    ; Return Value(s): Array
    ; Author(s): AspirinJunkie
    ;
    ;===============================================================================
    Func FileListCmd($sStPath, Const $sPat = '*', Const $iFlag = 0, Const $iSplitFlag = 2)
    ;by AspirinJunkie
    Local $sT = "", $sAtt
    Switch $iFlag
    Case 0
    $sAtt = ""
    Case 1
    $sAtt = ":-D"
    Case 2
    $sAtt = ":D"
    Case Else
    Return SetError(1, 0, 0)
    EndSwitch
    Local $iPID = Run(@ComSpec & ' /c DIR "' & $sPat & '" /A' & $sAtt & " /B /S", $sStPath, @SW_HIDE, 6)
    Do
    $sT &= StdoutRead($iPID)
    Until @error

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

    Return StringSplit(StringTrimRight(OemToChar($sT), 2), @CRLF, $iSplitFlag)
    EndFunc ;==>FileListCmd

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

    ;===============================================================================
    ; Name: OemToChar
    ; Description: Wandelt einen ASCII- in einen ANSI-String
    ; Parameter(s): $szSrc = String der umgewandelt werden soll
    ; Requirement(s): keine
    ; Return Value(s): bei Erfolg: umgewandelter String
    ; bei Fehler: "" und @error = 1
    ; Author(s): bernd670
    ;
    ;===============================================================================
    Func OemToChar(ByRef $szSrc)
    Local $strSrc = DllStructCreate("char[" & StringLen($szSrc) + 1 & "]")
    Local $strDst = DllStructCreate("char[" & StringLen($szSrc) * 2 + 1 & "]")
    DllStructSetData($strSrc, 1, $szSrc)
    DllStructSetData($strDst, 1, 0)
    Local $lRetVal = DllCall("user32.dll", "long", "OemToChar", "ptr", DllStructGetPtr($strSrc), "ptr", DllStructGetPtr($strDst))
    If IsArray($lRetVal) And $lRetVal[0] = 1 Then Return SetError(0, 0, DllStructGetData($strDst, 1))
    Return SetError(1, 0, "")
    EndFunc ;==>OemToChar

    [/autoit]
  • ok, aber das dauert ja so lange, dann mach ichs doch lieber in einer .bat datei,
    also hab ichs so richtig verstanden:

    *.bat

    Spoiler anzeigen

    AutoIT (nur die *.bat datei ausführen)

    Spoiler anzeigen
    [autoit]

    Shellexecute(*.bat)

    [/autoit]

    wenn das alles richtig ist, wäre das perfekt

  • Zur .bat-Datei:
    du hast dort "ÚTEI%" stehen wo "%DATEI%" stehen sollte.

    Zum Aufruf der bat aus dem AutoIt-Skript heraus:
    Es muss der Pfad zur Bat-Datei als String eingetragen werden.
    WildCards ( das * ) werden nicht unterstützt.
    Daher musst du die Datei mit Pfad schon richtig hinschreiben.
    Nur den Dateinamen anzugeben klappt nur wenn die Datei im Arbeitsverzeichnis des Skriptes liegt oder in einem Pfad welcher in der Umgebungsvariable PATH eingetragen ist.
    Außerdem wird ein String in AutoIt in Anführungsstriche gesetzt.

    Die reine AutoIt-Lösung sollte allerdings nicht viel langsamer sein da sowohl in der Bat wie auch hier nur der dir-Befehl abgesetzt wird.

  • also, kannst du mir die bat schreiben, komplett ohne fehler?

    also muss ich zum aufrufen das machen:

    Spoiler anzeigen
    [autoit]

    Shellexecute(@scriptdir & "IRGENTWAS.BAT")

    [/autoit]

    danke + mfg

  • Die bat hab ich doch schon geschrieben.
    Es muss nur bei "Set DATEI" der Dateiname angepasst werden.
    @Scriptdir brauchst du nicht unbedingt wenn dein Arbeitsverzeichnis gleich dem Skriptverzeichnis ist (was standard sein sollte).
    Ansonsten fehlt bei dir ein "\":

    [autoit]

    Shellexecute(@scriptdir & "\IRGENTWAS.BAT")

    [/autoit]