FTP Upload per _FTP_ProgressUpload

  • Die genannte Funktion verrichtet zwar ihre Arbeit, jedoch erscheint im Fenstertitel zwischen jeder Aktualisierung der Progressbar der Hinweis (Keine Rückmeldung). Habe schon diverse Dinge ausprobiert, die Meldung erscheint sowohl bei einer eigenen GUI (on event mode und auch im anderen gui mode) mit einem progress control, als auch wenn man statt einer GUI progressOn verwendet. Das selbe passiert auch ohne eigene Progressfunktion, also nur über die in der FTP Funktion enthaltene progressOn Variante. Ist das so normal? Kann man das irgendwie beheben?

    Verwende Vista x64, evtl passiert das unter anderen Betriebssystemen nicht?

    Hier das Beispielscript ohne FTP Daten:

    [autoit]


    #include <FTPEx.au3>
    #include <array.au3>
    #include <GUIConstantsEx.au3>
    #include <ProgressConstants.au3>
    #include <WindowsConstants.au3>
    #Region ### START Koda GUI section ### Form=
    Opt("GUIOnEventMode", 1) ; Change to OnEvent mode

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

    $Form1 = GUICreate("Form1", 414, 182, 355, 316)
    $Progress1 = GUICtrlCreateProgress(48, 72, 305, 41)
    $b1 = GUICtrlCreateButton("start",48,130)
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###
    GUISetOnEvent($GUI_EVENT_CLOSE, "exitgui")
    GUICtrlSetOnEvent($b1, "upload")

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

    While 1
    Sleep(500)
    WEnd

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

    Func upload()
    $server = 'entfernt'
    $username = 'entfernt'
    $pass = 'entfernt'

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

    $Open = _FTP_Open('MyFTP Control')
    $Conn = _FTP_Connect($Open, $server, $username, $pass, 1, 7878) ; passiv mode und port 7878
    $upload = _FTP_ProgressUpload($Conn, "F:\test.avi","test123.avi", "updateprogress" )
    MsgBox(0,"","Debug-Info:" & @lf & $upload & @LF & @error)

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

    $Ftpc = _FTP_Close($Open)
    EndFunc

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

    Func updateprogress($progress)
    GUICtrlSetData($Progress1,$progress)
    Return 1
    EndFunc

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

    func exitgui()
    Exit
    EndFunc

    [/autoit][autoit][/autoit][autoit][/autoit]
  • Zitat

    Verwende Vista x64, evtl passiert das unter anderen Betriebssystemen nicht?


    Ich verwende Windows XP. Der Hinweis (Keine Rückmeldung) kommt bei mir zwar nicht, dennoch ist das Fenster zwischen den aktualisierungen wie "eingefroren". :S

  • Ergänzung zu meinem obigen Beitrag:

    Wenn ich andauernd in das Fensterinnere klicke, dann erscheint bei mir ebenfalls der Hinweis (Keine Rückmeldung) aber nur kurz, dann ist der Titel wieder normal. Klicke ich dann weiter, dann kommt wieder der Hinweis, usw.

    misterspeed, du könntest ein 2. Skript schreiben.
    Im 1. ist nur die GUI und im 2. ist dann das FTP Zeug.
    Vom 1. rufst du dann mit Run das 2. auf.
    So ist es egal ob das 2. Skript immerwieder kurz laggt, dass 1. merkt dann davon nichts. ;)

    Habs so getestet und es funktioniert problemlos 8)

  • Ist halt unschön nur wegen der FTP Funktion ein zweites Scirpt laufen zulassen, mal davon ab, dass ich dann noch zusätzlichen Aufwand betreiben muss um im Hauptscript die Rückmeldungen des FTP Scripts zu erhalten. Verstehe auch nicht so recht, warum das passiert, denn sowas hab ich noch bei keiner anderen Fnktion beobachtet, egal wie rechen und zeitintensiv diese ist. Kann mir nur vorstellen, dass es mit den dll Aufrufen in der entsprechenden FTP Funktion zusammenhängt.

  • In der while Schleife der GUI ? Also anstatt der 500 eine 10? Wenn ja, hab ich eben versucht, macht keinen Unterschied. Das GUI Fenster lässt sich btw auch nur sehr schlecht bewegen während dem Upload. Also das Verschieben des Fensters wird extrem verzögert ausgeführt, als ob das ganze System ausgelastet wäre. CPU Last ist aber normal, andere Fenster lassen sich in "echtzeit" verschieben.

  • Hat leider auch keinen positiven effekt. Hab Pausen von 10, 200 und 1000 Milisekunden vor dem return getestet.

    EDIT: Bei kleinen Dateien (<100mb) erscheint diese Meldung nicht und das Fenster lässt sich deutlich besser bewegen. Je größer die Datei wird, desto stärker wird dieser Effekt.

    Einmal editiert, zuletzt von misterspeed (5. Dezember 2010 um 13:21)

  • Da ist bereits ein Sleep drin. Aber ich hab mir die Funktion mal genauer angeschaut. Soweit ich das verstanden habe passiert da folgendes:

    Die Datei die hochgeladen werden soll wird in 100 gleichgroße Teile aufgeteilt und dann wird in einer Schleife jedes Teil hochgeladen. Nachdem ein Teil hochgeladen wurde wird die Funktion zur Progress aktualisierung aufgerufen. Da also immer 100 Teile benutzt werden ist die Dauer eines Schleifendurchgangs von der Dateigröße und der Upload Bandbreite abhängig. Bei großen Dateien und einer niedrigen Bandbreite kann es also teilweise sehr lange dauern bis die Progressfunktion erneut aufgerufen wird. Möglicherweise führt das dann zum freezen der GUI?

    Hier mal die upload Funktion aus der ftpex.au3, vielleicht kann man das ja so umschreiben, dass die Anzahl der Parts abhängig von der Dateigröße und Bandbreite (per optionalem Parameter angeben?) gewählt wird, damit die Durchgänge nicht länger als x Sekunden dauern. Vielleicht liegts aber auch garnicht daran... ?(

    Spoiler anzeigen
    [autoit]


    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _FTP_ProgressUpload
    ; Description ...: Uploads a file in Binary Mode and shows a Progress window or by Calling a User defined Function.
    ; Syntax.........: _FTP_ProgressUpload($l_FTPSession, $s_LocalFile, $s_RemoteFile[, $FunctionToCall = ""])
    ; Parameters ....: $l_FTPSession - as returned by _FTP_Connect().
    ; $s_LocalFile - The local file.
    ; $s_RemoteFile - The remote Location for the file.
    ; $FunctionToCall - [Optional] A function which can update a Progressbar and
    ; react on UserInput like Click on Abort or Close App.
    ; (More info in the end of this comment)
    ; Return values .: Success: 1
    ; Error: 0 and @error:
    ; -3 -> Create File failed
    ; -4 -> Write to file failed
    ; -5 -> Close File failed
    ; -6 -> Download aborted by PercentageFunc, Return of Called Function
    ; Author ........: limette, Prog@ndy
    ; Modified.......:
    ; Remarks .......:
    ; Information about $FunctionToCall:
    ; Parameter: $Percentage - The Percentage of Progress
    ; Return Values: Continue Download - 1
    ; Abort Download - 0 Or negative
    ; These Return Values are returned by _FTP_UploadProgress, too,
    ; so you can react on different Actions like Aborting by User, closing App or TimeOut of whatever
    ;~ Examples:
    ;~ Func _UpdateProgress($Percentage)
    ;~ ProgressSet($percent,$percent &"%")
    ;~ If _IsPressed("77") Then Return 0 ; Abort on F8
    ;~ Return 1 ; bei 1 Fortsetzten
    ;~ Endfunc
    ;
    ;~ Func _UpdateProgress($Percentage)
    ;~ GUICtrlSetData($ProgressBarCtrl,$percent)
    ;~ Switch GUIGetMsg()
    ;~ Case $GUI_EVENT_CLOSE
    ;~ Return -1 ; _FTP_UploadProgress Aborts with -1, so you can exit you app afterwards
    ;~ Case $Btn_Cancel
    ;~ Return 0 ; Just Cancel, without special Return value
    ;~ EndSwitch
    ;~ Return 1 ; Otherwise contine Upload
    ;~ Endfunc
    ; Related .......:
    ; Link ..........: @@MsdnLink@@ FtpOpenFile
    ; Example .......:
    ; ===============================================================================================================================
    Func _FTP_ProgressUpload($l_FTPSession, $s_LocalFile, $s_RemoteFile, $FunctionToCall = "")
    If $__ghWinInet_FTP = -1 Then Return SetError(-2, 0, 0)
    Local $ai_InternetCloseHandle, $glen, $last, $x, $parts, $buffer, $ai_ftpwrite, $result, $out, $i, $ret

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

    Local $ai_ftpopenfile = DllCall($__ghWinInet_FTP, 'handle', 'FtpOpenFileW', 'handle', $l_FTPSession, 'wstr', $s_RemoteFile, 'dword', $GENERIC_WRITE, 'dword', $FTP_TRANSFER_TYPE_BINARY, 'dword_ptr', 0)
    If @error Or $ai_ftpopenfile[0] = 0 Then Return SetError(-3, _WinAPI_GetLastError(), 0)

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

    If $FunctionToCall = "" Then ProgressOn("FTP Upload", "Uploading " & $s_LocalFile)

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

    Local $fhandle = FileOpen($s_LocalFile, 16)

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

    $glen = FileGetSize($s_LocalFile)
    $last = Mod($glen, 100)

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

    $x = ($glen - $last) / 100
    If $x = 0 Then
    $x = $last
    $parts = 1
    ElseIf $last > 0 Then
    $parts = 101
    Else
    $parts = 100
    EndIf
    If $x < $last Then
    $buffer = DllStructCreate("byte[" & $last & "]")
    Else
    $buffer = DllStructCreate("byte[" & $x & "]")
    EndIf

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

    For $i = 1 To $parts
    Select
    Case $i = 101 And $last > 0
    $x = $last
    EndSelect
    DllStructSetData($buffer, 1, FileRead($fhandle, $x))

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

    $ai_ftpwrite = DllCall($__ghWinInet_FTP, 'bool', 'InternetWriteFile', 'handle', $ai_ftpopenfile[0], 'ptr', DllStructGetPtr($buffer), 'dword', $x, 'dword*', $out)
    If @error Or $ai_ftpwrite[0] = 0 Then
    Local $lasterror = _WinAPI_GetLastError()
    $ai_InternetCloseHandle = DllCall($__ghWinInet_FTP, 'bool', 'InternetCloseHandle', 'handle', $ai_ftpopenfile[0])
    ; No need to test @error.
    FileClose($fhandle)

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

    Return SetError(-4, $lasterror, 0)
    EndIf

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

    If $FunctionToCall == "" Then
    ProgressSet($i)
    Else
    Select
    Case $parts = 1
    $result = 100
    Case $i = 101
    $result = 100
    Case Else
    $result = $i
    EndSelect
    $ret = Call($FunctionToCall, $result)
    If $ret <= 0 Then
    $ai_InternetCloseHandle = DllCall($__ghWinInet_FTP, 'bool', 'InternetCloseHandle', 'handle', $ai_ftpopenfile[0])
    ; No need to test @error.
    DllCall($__ghWinInet_FTP, 'bool', 'FtpDeleteFileW', 'handle', $l_FTPSession, 'wstr', $s_RemoteFile)
    ; No need to test @error.
    FileClose($fhandle)
    Return SetError(-6, 0, $ret)
    EndIf
    EndiF
    Sleep(10)

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

    Next

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

    FileClose($fhandle)

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

    If $FunctionToCall = "" Then ProgressOff()

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

    $ai_InternetCloseHandle = DllCall($__ghWinInet_FTP, 'bool', 'InternetCloseHandle', 'handle', $ai_ftpopenfile[0])
    ; No need to test @error.
    If @error Or $ai_InternetCloseHandle[0] = 0 Then Return SetError(-5, 0, 0)

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

    Return 1
    EndFunc ;==>_FTP_ProgressUpload

    [/autoit]