FTP-Speicher nach einer Datei durchsuchen

  • Hi,
    mir wurde schon gesagt das man das obengenannte durch _FTP_FindFileFirst und _FTP_FindFileNext machen kann. Aber kapieren tu ich es überhaupt nicht. Im Grunde soll halt die erste Datei(FindFileFirst)gefunden werden, ausgegeben werden, gecheckt werden(ob es auch wirklich den User gibt), und wenn es ihn nicht gibt dann halt mit FindFileNext weitergemacht werden.
    Aber erstmal brauch ich nur Hilfe bei FindFileFirst. :D
    Hier mal mein Script. Was mach ich falsch?

    [autoit]

    #include <GUIConstants.au3>
    #include <FTPEx.au3>
    ;==============================================================================================
    $sAgent = "PvPonFireFTP" ;Fantasie Name
    $sServerName = "ftp.schmierdeinbrot.de"
    $sUserName = "********"
    $sPassword = "********"
    $lFileName = "/files/pvponfire/users/nakroma.ini"
    $sPath = "/files/pvponfire/users/"
    ;==============================================================================================
    #Region ### START Koda GUI section ### Form=
    $Form1 = GUICreate("PvPoF Launcher", 484, 304, 246, 312)
    $Input1 = GUICtrlCreateInput("", 185, 72, 121, 21)
    $Label1 = GUICtrlCreateLabel("Benutzer-ID", 215, 48, 60, 17)
    $Input2 = GUICtrlCreateInput("", 185, 122, 121, 21)
    $Label2 = GUICtrlCreateLabel("Passwort", 222, 104, 47, 17)
    $Button1 = GUICtrlCreateButton("Anmelden", 208, 152, 75, 25, 0)
    $Button2 = GUICtrlCreateButton("Registrieren", 208, 184, 75, 25, 0)
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###

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

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $Button1
    $lSession = _FTP_Open($sAgent)
    $hConnect = _FTP_Connect($lSession, $sServerName, $sUserName, $sPassword)
    Local $hHandle
    $fFileFirst = _FTP_FindFileFirst($hConnect, $sPath, $hHandle)
    MsgBox(0, "", $fFileFirst)
    EndSwitch
    WEnd

    [/autoit]


    Aber in der MsgBox wird nicht die erste Datei ausgegeben.
    Danke für die Hilfe schon mal im Vorraus.
    Mfg

    2 Mal editiert, zuletzt von Nakroma (9. April 2011 um 15:04)

  • Folgendes Beispiel gibt dir alle Ordner und Dateien in allen Ebenen als Array zurück.
    Leicht abgewandelt kannst du es auch zum reinen Suchen verwenden:

    Spoiler anzeigen
    [autoit]

    #include <ftpEx.au3>
    #include <array.au3>

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

    $server = 'ftp.csx.cam.ac.uk'
    $username = ''
    $pass = ''

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

    $hFTP = _FTP_Open('FTP_open')
    $hFTPCon = _FTP_Connect($hFTP, $server, $username, $pass)

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

    $aFileList = _FTP_FileList($hFTPCon, "pub/software/antivirus/")
    _ArrayDisplay($aFileList)

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

    ; #FUNCTION# ======================================================================================
    ; Name ..........: _FTP_FileList()
    ; Description ...: Listet alle Dateien und Ordner in allen Ebenen eines FTP-Pfades
    ; Syntax ........: _FTP_FileList(Const $hConn[, $sPath = ""])
    ; Parameters ....: Const $hConn - Handle zu einer offenen FTP-Verbindung. (z.B. mit FTP_Open)
    ; $sPath - [optional] Ordnerpfad auf dem Server welcher durchsucht werden soll (default:"")
    ; Return values .: Success: Array mit Datei/Ordnernamen
    ; Failure: Setzt @error = 1 und Array[0] = -1
    ; Author ........: Andy
    ; Related .......: #include <ftpEx.au3>
    ; =================================================================================================
    Func _FTP_FileList(Const $hConn, $sPath = "")
    ;by AspirinJunkie
    Local $cSQueue = ObjCreate("System.Collections.Queue")
    Local $oRetDict = ObjCreate("Scripting.Dictionary")
    Local $hFFFF, $aNext, $sCurrentPath

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

    If StringRight($sPath, 1) = "/" Then $sPath = StringTrimRight($sPath, 1)
    $cSQueue.Enqueue($sPath)

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

    While $cSQueue.Count > 0
    $sCurrentPath = $cSQueue.Dequeue

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

    $aNext = _FTP_FindFileFirst($hConn, $sCurrentPath, $hFFFF)
    If @error Then
    If $oRetDict.Count > 0 Then ContinueLoop
    Local $Ret[1] = [-1]
    Return SetError(1, 0, $Ret)
    EndIf

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

    ConsoleWrite($aNext & @CRLF)

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

    If BitAND($aNext[1], 16) Then $cSQueue.Enqueue($sCurrentPath & '/' & $aNext[10])
    $oRetDict.Add($sCurrentPath & '/' & $aNext[10], 0)

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

    Do
    $aNext = _FTP_FindFileNext($hFFFF)
    If @error Then ExitLoop
    If BitAND($aNext[1], 16) Then $cSQueue.Enqueue($sCurrentPath & '/' & $aNext[10])
    $oRetDict.Add($sCurrentPath & '/' & $aNext[10], 0)
    Until 0
    _FTP_FindFileClose($hFFFF)
    WEnd

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

    If $oRetDict.Count > 0 Then
    Return $oRetDict.Keys
    Else
    Local $Ret[1] = [0]
    Return SetError(2, 0, $Ret)
    EndIf
    EndFunc ;==>_FTP_FileListRekursiv

    [/autoit]

    Edit: Wenn es, was zwar dein Titel suggeriert, nicht um das Durchsuchen eines Verzeichnisbaumes auf einem FTP-Server nach einer Datei geht sondern nur darum zu schauen ob eine Datei in dem Verzeichnis überhaupt existiert dann schau dir mal nochmal kurz das Beispiel in der Hilfe zu _FTP_FindFileFirst() nochmal ganz genau an.
    Kleiner Tipp: Die Funktion gibt ein Array zurück.

    Einmal editiert, zuletzt von AspirinJunkie (9. April 2011 um 10:31)

  • Edit: Wenn es, was zwar dein Titel suggeriert, nicht um das Durchsuchen eines Verzeichnisbaumes auf einem FTP-Server nach einer Datei geht sondern nur darum zu schauen ob eine Datei in dem Verzeichnis überhaupt existiert dann schau dir mal nochmal kurz das Beispiel in der Hilfe zu _FTP_FindFileFirst() nochmal ganz genau an.
    Kleiner Tipp: Die Funktion gibt ein Array zurück.


    Hab sogar genau das kopiert was im Beispiel steht, aber es geht nicht

  • Das Beispiel funktioniert einwandfrei.
    Wenn du die aktuelle AutoIt-Version hast sollte es folgende Ausgabe in der SciTe4AutoIt-Konsole bringen:

    Code
    $Filename = Contrib Attribute = 16  -> Fehlercode: 0


    So oder so - der Hinweis von mir ist immer noch gültig für dein Beispiel: _FTP_FindFileFirst() gibt ein Array zurück - du verwendest es aber wie eine Einzelvariable.

  • Hier die While:

    [autoit]


    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $Button1
    $lSession = _FTP_Open($sAgent)
    $hConnect = _FTP_Connect($lSession, $sServerName, $sUserName, $sPassword)
    Local $h_Handle
    $aFile = _FTP_FindFileFirst($hConnect, "/pub/software/programming/pcre/", $h_Handle)
    ConsoleWrite('$Filename = ' & $aFile[10] & ' Attribute = ' & $aFile[1] & ' -> Fehlercode: ' & @error & @crlf)
    EndSwitch
    WEnd

    [/autoit]


    Hier der Fehlercode:

    [autoit]

    C:\Users\Tarek\Desktop\Zeugs\Autoit\PvPonFire\start.au3 (36) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:
    ConsoleWrite('$Filename = ' & $aFile[10] & ' Attribute = ' & $aFile[1] & ' -> Fehlercode: ' & @error & @crlf)
    ConsoleWrite('$Filename = ' & ^ ERROR

    [/autoit]
  • Joar dann wurde wohl nix gefunden was auch daran liegen dürfte, dass du den Pfad auf dem ftp Server 1:1 aus der Hilfe entnommen hast und dieser bei dir sehr wahrscheinlich nicht existiert. Du solltest auf jedenfall vor der Ausgabe des Suchergebnisses mit isArray prüfen ob etwas gefunden wurde oder nicht. Und dann eben eine Fehler Msgbox anstelle des Array Inhaltes ausgeben: "Verzeichnis nicht gefunden".

    Ausserdem sollte natürlich erstmal sichergestellt werden, dass der FTP connect überhaupt erfolgreich war, auch hier sollte der Rückgabewert kontrolliert werden und nur dann nach Dateien gesucht werden wenn alles ok ist.

  • Ahh, jetzt gehts, danke sehr :)
    €:
    Das Klappt schonmal:

    [autoit]


    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $Button1
    $lSession = _FTP_Open($sAgent)
    $hConnect = _FTP_Connect($lSession, $sServerName, $sUserName, $sPassword)
    Local $hHandle
    $aFile = _FTP_FindFileFirst($hConnect, $sPath, $hHandle)
    If GUICtrlRead($Input1) & ".ini" = $aFile[10] Then
    MsgBox(0, "", "Benutzer gefunden")
    Else
    For $i = 0 To 500
    $aFile2 = _FTP_FindFileNext($hHandle)
    If GUICtrlRead($Input1) & ".ini" = $aFile2[10] Then
    MsgBox(0, "", "Benutzer gefunden")
    ExitLoop
    EndIf
    Next
    EndIf
    EndSwitch
    WEnd

    [/autoit]

    Allerdings, wenn man etwas falsches eingibt dann kommt:

    [autoit]


    If GUICtrlRead($Input1) & ".ini" = $aFile2[10] Then
    If GUICtrlRead($Input1) & ".ini" = ^ ERROR

    [/autoit]

    Wie kann ich das korrigieren?

    Einmal editiert, zuletzt von Nakroma (9. April 2011 um 15:04)

  • Naja immernoch der selbe Fehler weil du eben immernoch nicht prüfst ob die Suche überhaupt erfolgreich war und ein Array zurückgegeben wurde. Du kannst eine Variable nicht als Array ansprechen wenn sie garkein Array ist. Deshalb prüft man sowas zuerst.

  • [autoit]


    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $Button1
    $lSession = _FTP_Open($sAgent)
    $hConnect = _FTP_Connect($lSession, $sServerName, $sUserName, $sPassword)
    Local $hHandle
    $aFile = _FTP_FindFileFirst($hConnect, $sPath, $hHandle)
    If GUICtrlRead($Input1) & ".ini" = $aFile[10] Then
    MsgBox(0, "", "Benutzer gefunden")
    Else
    For $i = 0 To 500
    $aFile2 = _FTP_FindFileNext($hHandle)
    If IsArray($aFile[10]) Then
    If GUICtrlRead($Input1) & ".ini" = $aFile2[10] Then
    MsgBox(0, "", "Benutzer gefunden")
    ExitLoop
    EndIf
    Else
    MsgBox(0, "ERROR", "")
    ExitLoop
    EndIf
    Next
    EndIf
    EndSwitch
    WEnd

    [/autoit]

    So hab ichs jetzt, blos wenn ich einen Benutzer angebe der im FTP-Speicher nicht an erster oder zweiter Stelle steht, kommt eben ERROR.

  • 1. Fehlt die Prüfung auf ein gültiges Array auch noch bei FindFileFirst
    2. Prüfst du bei FindFileNext das falsche array
    3. hast du isArray falsch angewendet und prüfst nicht die Variable sondern einen Wert des Arrays, von dem du ja erstmal wissen willst ob es überhaupt existiert

    [autoit]


    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $Button1
    $lSession = _FTP_Open($sAgent)
    $hConnect = _FTP_Connect($lSession, $sServerName, $sUserName, $sPassword)
    if $hConnect <> 0 Then ; nur wenn der connect funktioniert hat...
    Local $hHandle
    $aFile = _FTP_FindFileFirst($hConnect, $sPath, $hHandle)
    if IsArray($aFile) Then ; wenn die Variable ein Array ist dann...
    If GUICtrlRead($Input1) & ".ini" = $aFile[10] Then
    MsgBox(0, "", "Benutzer gefunden")
    Else
    For $i = 0 To 500 ; warum auch immer du hier 500 Durchläufe machst...
    $aFile2 = _FTP_FindFileNext($hHandle)
    If IsArray($aFile2) Then ; Wenn es noch eine nächste Datei gibt...
    If GUICtrlRead($Input1) & ".ini" = $aFile2[10] Then
    MsgBox(0, "", "Benutzer gefunden")
    ExitLoop
    EndIf
    Else
    MsgBox(0, "Fehler", "Benutzer konnte nicht gefunden werden.")
    ExitLoop
    EndIf
    Next
    EndIf
    Else
    MsgBox(0,"Fehler","Verzeichnis wurde nicht gefunden oder es befinden sich keine Dateien im Verzeichnis.")
    EndIf
    Else
    MsgBox(0,"Fehler","FTP Verbindung konnte nicht hergestellt werden.")
    EndIf
    EndSwitch
    WEnd

    [/autoit]
  • Funktioniert ganz gut, blos das wenn man einen falschen namen eingibt dieser error kommt:

    [autoit]


    If GUICtrlRead($Input1) & ".ini" = $aFile2[10] Then
    If GUICtrlRead($Input1) & ".ini" = ^ ERROR

    [/autoit]

    Ist ja das gleiche wie vorhin
    Bzw. steh ich iwie aufm Schlauch

  • Hast du mein überarbeitetes Script übernommen? Ohne FTP Daten kann ich das zwar nicht testen, aber auf anhieb sieht das fehlerfrei aus, was ich dir da zusammengebastelt habe. Poste nochmal die aktuelle Fassung deines Scriptes.

  • [autoit]


    $sServerName = "ftp.schmierdeinbrot.de"
    $sUserName = "***********"
    $sPassword =" *********"
    $lFileName = "/files/pvponfire/users/nakroma.ini"
    $sPath = "/files/pvponfire/users"
    ;==============================================================================================
    #Region ### START Koda GUI section ### Form=
    $Form1 = GUICreate("PvPoF Launcher", 484, 304, 246, 312)
    $Input1 = GUICtrlCreateInput("", 185, 72, 121, 21)
    $Label1 = GUICtrlCreateLabel("Benutzer-ID", 215, 48, 60, 17)
    $Input2 = GUICtrlCreateInput("", 185, 122, 121, 21)
    $Label2 = GUICtrlCreateLabel("Passwort", 222, 104, 47, 17)
    $Button1 = GUICtrlCreateButton("Anmelden", 208, 152, 75, 25, 0)
    $Button2 = GUICtrlCreateButton("Registrieren", 208, 184, 75, 25, 0)
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###

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

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $Button1
    $lSession = _FTP_Open($sAgent)
    $hConnect = _FTP_Connect($lSession, $sServerName, $sUserName, $sPassword)
    if $hConnect <> 0 Then ; nur wenn der connect funktioniert hat...
    Local $hHandle
    $aFile = _FTP_FindFileFirst($hConnect, $sPath, $hHandle)
    if IsArray($aFile) Then ; wenn die Variable ein Array ist dann...
    If GUICtrlRead($Input1) & ".ini" = $aFile[10] Then
    MsgBox(0, "", "Benutzer gefunden")
    Else
    For $i = 0 To 500 ; warum auch immer du hier 500 Durchläufe machst...
    $aFile2 = _FTP_FindFileNext($hHandle)
    If IsArray($aFile2) Then ; Wenn es noch eine nächste Datei gibt...
    If GUICtrlRead($Input1) & ".ini" = $aFile2[10] Then
    MsgBox(0, "", "Benutzer gefunden")
    ExitLoop
    EndIf
    Else
    MsgBox(0, "Fehler", "Benutzer konnte nicht gefunden werden.")
    ExitLoop
    EndIf
    Next
    EndIf
    Else
    MsgBox(0,"Fehler","Verzeichnis wurde nicht gefunden oder es befinden sich keine Dateien im Verzeichnis.")
    EndIf
    Else
    MsgBox(0,"Fehler","FTP Verbindung konnte nicht hergestellt werden.")
    EndIf
    EndSwitch
    WEnd

    [/autoit]
  • Und welche Fehlermedlungen kommen im Scite Editor jetzt noch? Bitte komplettes Konsolen Log inklusive Zeilenangabe des Fehlers.
    Davon mal ab sagt mir mein Editor beim Syntax check, dass die beiden includes fehlen und dass die Variable $sAgent nicht deklariert ist. Vielleicht haste das aber nur vergessen hier mit zuposten.

    Das hier also mal noch hinzufügen, wenn du willst das es überhaupt mal jemand testen kann.

    [autoit]


    #include <GUIConstants.au3>
    #include <FTPEx.au3>
    $sAgent = "myFTP"

    [/autoit]
  • Fehler gefunden. Die Hilfe zu filefindfirst und filefindnext ist hier etwas irreführend. Im Fehlerfall wird nicht 0 zurückgegeben sondern ein Array, dessen Element 0 den Wert 0 hat, deswegen war die Prüfung ob ein Array zurückgegeben wurde auch immer True, was dann natürlich zum Fehler führt wenn man auf das 10. Element zugreifen will. So sollte es nun funktionieren:

    Spoiler anzeigen
    [autoit]


    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $Button1
    $lSession = _FTP_Open($sAgent)
    $hConnect = _FTP_Connect($lSession, $sServerName, $sUserName, $sPassword,1,7878)
    if $hConnect <> 0 Then ; nur wenn der connect funktioniert hat...
    Local $hHandle
    $aFile = _FTP_FindFileFirst($hConnect, $sPath, $hHandle)
    If IsArray($aFile) And $aFile[0] <> 0 Then ; wenn die Variable ein Array ist dann...
    If GUICtrlRead($Input1) & ".ini" = $aFile[10] Then
    MsgBox(0, "", "Benutzer gefunden oben")
    Else
    For $i = 0 To 500 ; warum auch immer du hier 500 Durchläufe machst...
    $aFile2 = _FTP_FindFileNext($hHandle)
    If IsArray($aFile2) And $aFile2[0] <> 0 Then ; Wenn es noch eine nächste Datei gibt...
    If GUICtrlRead($Input1) & ".ini" = $aFile2[10] Then
    MsgBox(0, "", "Benutzer gefunden unten")
    ExitLoop
    EndIf
    Else
    MsgBox(0, "Fehler", "Benutzer konnte nicht gefunden werden.")
    ExitLoop
    EndIf
    Next
    EndIf
    Else
    MsgBox(0,"Fehler","Verzeichnis wurde nicht gefunden oder es befinden sich keine Dateien im Verzeichnis.")
    EndIf
    _ftp_close($lSession)
    Else
    MsgBox(0,"Fehler","FTP Verbindung konnte nicht hergestellt werden.")
    EndIf
    EndSwitch
    WEnd

    [/autoit]

    EDIT:

    _ftp_close() sollte man btw auch nicht vergessen am Ende, hab das mal noch mit eingebaut.

    2 Mal editiert, zuletzt von misterspeed (11. April 2011 um 22:06)

  • Es kommt immer, FTP Verbindung fehlgeschlagen...
    Hab mich sogar nochmal eingeloggt, also iwas muss da falsch sein...
    €:

    [autoit]

    $hConnect = _FTP_Connect($lSession, $sServerName, $sUserName, $sPassword,1,7878)

    [/autoit]


    hab die letzten beiden zahlen weggemacht, es geht danke dir :D

    €€: Ich hab 500 Durchläufe gemacht, weil es ja alle User durchsuchen soll.

  • Jo sorry mein Fehler, hatte zum testen den eigenen FTP Server verwendet und wohl vergessen den Port und Passivmodus wieder zu entfernen.
    Deine 500 Durchläufe machen trotzdem keinen Sinn. Was ist wenn im Verzeichnis mehr als 500 Dateien sind? Benutz lieber eine Endlosschleife, denn du verlässt diese ja sowieso nicht durch einen Zähler sondern durch exitloop sobald keine Dateien mehr gefunden werden.