FTPUpload per InternetWriteFile

  • Oh, mir fällt da grad noch etwas auf ...

    Warum wird denn nicht in jedem Durchgang der Schleife der selbe Teil hochgeladen ?
    Ich meine, da steht doch einfach nur:

    DllStructSetData($buffer,1,FileRead($fhandle,$x))

    Warum geht der die Datei durch und liest nicht immer die ersten 100 Byte ein .. ?

    limette =)

    There are only 10 types of people in the world:
    Those who understand binary - and those who don't.

  • So, jetzt geht alles einwandfrei ( Es wird halt alles im Binary-Mode übertragen ;) )
    Hab die For Schleife angepasst, damit jetzt alles geht ;)
    ( 1 Part bei Datein < 100 bytes
    100 parts bei Dateien mit Mod($len,100) = 0
    101 Parts bei Dateien, die sich nicht glatt durch 100 Teilen lassen. )

    Spoiler anzeigen
    [autoit]

    $serv = "progandy.pr.funpic.de"

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

    $x = _FTP_Upload( $serv, $username, $pass, 'testdatei.txt' , "D:\hi.txt")
    ;~ MsgBox( 0, '', $x & '-' & @error )
    ;~ $FileLocal = "D:\Dokumente\Dateien von Andreas\Eigene Bilder\1.jpg"

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

    Func _FTP_Upload( $server, $user, $password, $file,$FileLocal )
    #Region connect
    Local $aiWinInetDLL = DllOpen("wininet.dll"), $ai_InternetCloseHandle,$parts
    Local $ai_InternetOpen = DllCall($aiWinInetDLL, 'long', 'InternetOpen', 'str', 'PicTransfer', 'long', 1, 'str', '', 'str', '', 'long', 0)
    If @error Or $ai_InternetOpen[0] = 0 Then
    DllClose($aiWinInetDLL)
    SetError(-1)
    Return 0
    EndIf

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

    Local $i_ServerPort = 0, $l_Service = 1, $l_Context = 0, $l_InternetSession = $ai_InternetOpen[0]
    Local $ai_InternetConnect = DllCall($aiWinInetDLL , 'long', 'InternetConnect', 'long', $l_InternetSession, 'str', $server, 'int', $i_ServerPort, 'str', $user, 'str', $password, 'long', $l_Service, 'long', 0x08000000, 'long', $l_Context)
    If @error Or $ai_InternetConnect[0] = 0 Then
    $ai_InternetCloseHandle = DllCall($aiWinInetDLL , 'int', 'InternetCloseHandle', 'long', $ai_InternetOpen[0])
    DllClose($aiWinInetDLL)
    SetError(-2)
    Return 0
    EndIf

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

    Local $ai_ftpopenfile = DllCall( $aiWinInetDLL , 'long', 'FtpOpenFile', 'long', $ai_InternetConnect[0], 'str', $file, 'dword', 0x40000000, 'dword', 0x02, 'dword', 0 )
    If @error Or $ai_ftpopenfile[0] = 0 Then
    $ai_InternetCloseHandle = DllCall($aiWinInetDLL , 'int', 'InternetCloseHandle', 'long', $ai_InternetConnect[0])
    $ai_InternetCloseHandle = DllCall($aiWinInetDLL , 'int', 'InternetCloseHandle', 'long', $ai_InternetOpen[0])
    DllClose($aiWinInetDLL)
    SetError(-3)
    Return 0
    EndIf
    #EndRegion

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

    #Region DataSend
    Local $fhandle = FileOpen($FileLocal,16)
    ;~ $buffer = FileRead( $fhandle )

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

    $glen = FileGetSize($FileLocal)
    $last = Mod($glen,100)
    $x = ($glen-$last)/100
    ;~ If $x = 0 Then $x = 1
    If $x = 0 Then
    $x = $last
    $parts = 1
    ElseIf $last > 0 Then
    $parts = 101
    Else
    $parts = 100
    EndIf
    $buffer = DllStructCreate("byte[" & $x & "]")

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

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

    Local $ai_ftpwrite = DllCall( $aiWinInetDLL , 'int', 'InternetWriteFile', 'long', $ai_ftpopenfile[0], 'ptr', DllStructGetPtr($buffer), 'int', $x, 'dword*', $out )
    $result += $ai_ftpwrite[4]
    If @error Or $ai_ftpwrite[0] = 0 Then
    $ai_InternetCloseHandle = DllCall($aiWinInetDLL , 'int', 'InternetCloseHandle', 'long', $ai_InternetConnect[0])
    $ai_InternetCloseHandle = DllCall($aiWinInetDLL , 'int', 'InternetCloseHandle', 'long', $ai_InternetOpen[0])
    FileClose($fhandle)
    DllClose($aiWinInetDLL)
    SetError(-4)
    Return 0
    EndIf

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

    ToolTip( $i )
    Sleep( 20 )

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

    Next

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

    FileClose($fhandle)
    #EndRegion

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

    #region disconnect
    $ai_InternetCloseHandle = DllCall($aiWinInetDLL , 'int', 'InternetCloseHandle', 'long', $ai_InternetConnect[0])
    $ai_InternetCloseHandle = DllCall($aiWinInetDLL , 'int', 'InternetCloseHandle', 'long', $ai_InternetOpen[0])
    If @error Or $ai_InternetCloseHandle[0] = 0 Then
    DllClose($aiWinInetDLL)
    SetError(-5)
    Return 0
    EndIf
    #EndRegion
    DllClose($aiWinInetDLL)
    Return 1
    EndFunc

    [/autoit]


    Idee zur Erweiterung: Eine Funktion, die bei jedem Durchgang aufgerufen wird, eine Abbruchbedingung prüft und auch eine GUI aktualisieren kann ;)

    [autoit]

    Func _UpdateParts($percent)
    GUICtrlSetData($progress,$percent)
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    Return -1 ; In Upload einn Abbruch einbauen, der negative Werte als Return angibt :) dann im Haupt-Programm testen.
    Case $Cancel
    Return 0 ; bei 0 Abbruch
    EndSwitch
    Return 1 ; bei 1 Fortsetzten
    Endfunc

    [/autoit]

    //Edti: Der schiebt den Lesepointer nach dem Lesen immer weiter, sodass der nächste Teil gelesen werden kann. Das geht, solaneg die Datei geöffnet bleibt. Das ist sie ja, Da sie zuerst mit FiloeOpen geöffnet wird und dann der Pointer auf die geöffnete Datei übergeben wird.

  • 1. Danke für den Fix mit dem 100 Byte-Dateien =)
    2. Gute Idee, werde ich einbauen, aber erstmal überhaupt die Funktion, das wird schon kompliziert genug ;)
    3. Ich arbeite viel zu selten mit FileOpen / FileClose... habe das mal getestet und das zu verstehen ^^
    Test.txt : 1234567890

    [autoit]

    $handle = FileOpen( 'test.txt', 0 )
    $a = FileRead( $handle, 5 )
    $b = FileRead( $handle, 5 )
    MsgBox( 0, 'a', $a )
    MsgBox( 0, 'b', $b )
    FileClose( $handle )

    [/autoit]


    Ausgabe:
    a: 12345
    b: 67890
    Und genau das wusste ich nicht :D
    Gut gut, nochmal danke =)
    Mal wieder viel gelernt ^^

    mfg limette

    There are only 10 types of people in the world:
    Those who understand binary - and those who don't.

  • Hallo limette

    Ja, das mit dem FileRead Handle habe ich noch nicht ganz verstanden. Besser gesagt verstehe ich nicht, wiede er das erste mal ab dem ersten Buchstaben 5 Zeichen ließt und beim zweiten mal die nächsten 5 Zeichen. Beide male ist außer die Variable der gleiche Leseaufruf, der da heißt lese 5 Zeichen / Buchstaben oder was auch immer da ist.
    Da kann es sein, das ich blond bin, aber eine Erklärung wäre echt gut.

    Crazy-A ?(

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

  • Ich habs mit diesem Test verstanden :]

    Also...

    Wenn ich nehme:

    [autoit]


    $a = FileRead( 'test.txt', 5 )
    $b = FileRead( 'test.txt', 5 )

    [/autoit]


    Dann ist $a = $b = 12345,
    denn FileRead mit Dateinamen und nicht Handle als Parameter ist das gleiche wie:

    [autoit]


    $handle = FileOpen( 'test.txt', 0 )
    $a = FileRead( $handle, 5 )
    FileClose( $handle )
    $handle = FileOpen( 'test.txt', 0 )
    $b = FileRead( $handle, 5 )
    FileClose( $handle )

    [/autoit]

    Wenn ich aber die Datei geöffnet lasse rückt er mit dem Pointer weiter, wie progandy schon sagte =)

    mfg limette

    There are only 10 types of people in the world:
    Those who understand binary - and those who don't.

  • Okay, das sollte ich mir mal schmerzfrei durch den Kopf gehen lassen.
    Ab besten ich gehe jetzt etwas shoppen, da bekommt Frau bekanntlich ja am besten den Kopf frei.

    Also bis späääääter.

    Crazy-A

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

  • FileOpen: Erstellt eine DLLStruct oder so, unteranderem mit Lese/SchreibMethode und Lese/SchreibPointer ( Beim Lesen Anfangs auf Pos. 0)
    FileRead: Ließt an der Stelle des LesePointers und schiebt ihn an das Ende des gelesenen Abschnitts
    FileClose : Entfernt die DLLStruktur

    ohne FileOPen/FileClose macht das alles FileRead. Dabei wird dann der Pointer eben jedesmal neu auf 0 gesetzt Und immer vom Anfang gelesen.
    //Edit: Jetzt mit möglichem Funtions aufruf und es sollten alle InternetClose Handles eingebaut sein.: Meiner Meinung nach sollte das noch auf die FTP.au3 angepasst werden :) ( Mach ich dann als nächstes, wenn ich Lust hab :)

    Spoiler anzeigen
    [autoit]

    #include <Misc.au3>

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

    ProgressOn("Upload","Uploading file [Cancel with F8]")
    $x = _FTP_Upload( $serv, $username, $pass, 'testdatei.jpg' , "D:\Dokumente\Dateien von Andreas\Eigene Bilder\1.jpg","_UpdateParts")
    ProgressSet(100,"Return: " & $x & @CRLF & "Error: " & @error)
    Sleep(2000)
    ProgressOff()

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

    Func _UpdateParts($percent)
    ProgressSet($percent,$percent &"%")
    If _IsPressed("77") Then Return 0
    ;~ Switch GUIGetMsg()
    ;~ Case $GUI_EVENT_CLOSE
    ;~ Return -1 ; In Upload einn Abbruch einbauen, der negative Werte als Return angibt :) dann im Haupt-Programm testen.
    ;~ Case $Cancel
    ;~ Return 0 ; bei 0 Abbruch
    ;~ EndSwitch
    Return 1 ; bei 1 Fortsetzten
    Endfunc

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

    Func _FTP_Upload( $server, $user, $password, $file,$FileLocal ,$FunctionToCall="")
    #Region connect
    Local $aiWinInetDLL = DllOpen("wininet.dll"), $ai_InternetCloseHandle,$parts
    Local $ai_InternetOpen = DllCall($aiWinInetDLL, 'long', 'InternetOpen', 'str', 'PicTransfer', 'long', 1, 'str', '', 'str', '', 'long', 0)
    If @error Or $ai_InternetOpen[0] = 0 Then
    DllClose($aiWinInetDLL)
    SetError(-1)
    Return 0
    EndIf

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

    Local $i_ServerPort = 0, $l_Service = 1, $l_Context = 0, $l_InternetSession = $ai_InternetOpen[0]
    Local $ai_InternetConnect = DllCall($aiWinInetDLL , 'long', 'InternetConnect', 'long', $l_InternetSession, 'str', $server, 'int', $i_ServerPort, 'str', $user, 'str', $password, 'long', $l_Service, 'long', 0x08000000, 'long', $l_Context)
    If @error Or $ai_InternetConnect[0] = 0 Then
    $ai_InternetCloseHandle = DllCall($aiWinInetDLL , 'int', 'InternetCloseHandle', 'long', $ai_InternetOpen[0])
    DllClose($aiWinInetDLL)
    SetError(-2)
    Return 0
    EndIf

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

    Local $ai_ftpopenfile = DllCall( $aiWinInetDLL , 'long', 'FtpOpenFile', 'long', $ai_InternetConnect[0], 'str', $file, 'dword', 0x40000000, 'dword', 0x02, 'dword', 0 )
    If @error Or $ai_ftpopenfile[0] = 0 Then
    $ai_InternetCloseHandle = DllCall($aiWinInetDLL , 'int', 'InternetCloseHandle', 'long', $ai_InternetConnect[0])
    $ai_InternetCloseHandle = DllCall($aiWinInetDLL , 'int', 'InternetCloseHandle', 'long', $ai_InternetOpen[0])
    DllClose($aiWinInetDLL)
    SetError(-3)
    Return 0
    EndIf
    #EndRegion

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

    #Region DataSend
    Local $fhandle = FileOpen($FileLocal,16)
    ;~ $buffer = FileRead( $fhandle )

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

    $glen = FileGetSize($FileLocal)
    $last = Mod($glen,100)
    $x = ($glen-$last)/100
    ;~ If $x = 0 Then $x = 1
    If $x = 0 Then
    $x = $last
    $parts = 1
    ElseIf $last > 0 Then
    $parts = 101
    Else
    $parts = 100
    EndIf
    $buffer = DllStructCreate("byte[" & $x & "]")

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

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

    Local $ai_ftpwrite = DllCall( $aiWinInetDLL , 'int', 'InternetWriteFile', 'long', $ai_ftpopenfile[0], 'ptr', DllStructGetPtr($buffer), 'int', $x, 'dword*', $out )
    $result += $ai_ftpwrite[4]
    If @error Or $ai_ftpwrite[0] = 0 Then
    $ai_InternetCloseHandle = DllCall($aiWinInetDLL , 'int', 'InternetCloseHandle', 'long', $ai_ftpopenfile[0])
    $ai_InternetCloseHandle = DllCall($aiWinInetDLL , 'int', 'InternetCloseHandle', 'long', $ai_InternetConnect[0])
    $ai_InternetCloseHandle = DllCall($aiWinInetDLL , 'int', 'InternetCloseHandle', 'long', $ai_InternetOpen[0])
    FileClose($fhandle)
    DllClose($aiWinInetDLL)
    SetError(-4)
    Return 0
    EndIf

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

    Switch $FunctionToCall
    Case ""
    ToolTip( $i )
    Case Else
    $Ret = Call($FunctionToCall,$i)
    Select
    Case $Ret <= 0
    $ai_InternetCloseHandle = DllCall($aiWinInetDLL , 'int', 'InternetCloseHandle', 'long', $ai_ftpopenfile[0])
    DllCall($aiWinInetDLL, 'int', 'FtpDeleteFile', 'long', $ai_InternetConnect[0], 'str', $file)
    $ai_InternetCloseHandle = DllCall($aiWinInetDLL , 'int', 'InternetCloseHandle', 'long', $ai_InternetConnect[0])
    $ai_InternetCloseHandle = DllCall($aiWinInetDLL , 'int', 'InternetCloseHandle', 'long', $ai_InternetOpen[0])
    FileClose($fhandle)
    DllClose($aiWinInetDLL)
    SetError(-6)
    Return $Ret
    EndSelect
    EndSwitch
    Sleep( 20 )

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

    Next

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

    FileClose($fhandle)
    #EndRegion

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

    #region disconnect
    $ai_InternetCloseHandle = DllCall($aiWinInetDLL , 'int', 'InternetCloseHandle', 'long', $ai_ftpopenfile[0])
    $ai_InternetCloseHandle = DllCall($aiWinInetDLL , 'int', 'InternetCloseHandle', 'long', $ai_InternetConnect[0])
    $ai_InternetCloseHandle = DllCall($aiWinInetDLL , 'int', 'InternetCloseHandle', 'long', $ai_InternetOpen[0])
    If @error Or $ai_InternetCloseHandle[0] = 0 Then
    DllClose($aiWinInetDLL)
    SetError(-5)
    Return 0
    EndIf
    #EndRegion
    DllClose($aiWinInetDLL)
    Return 1
    EndFunc

    [/autoit]

    Einmal editiert, zuletzt von progandy (7. Juni 2008 um 15:15)

  • @progandy

    Zeile 4:
    $x = _FTP_Upload( $serv, $username, $pass, 'testdatei.jpg' , "D:\Dokumente\Dateien von Andreas\Eigene Bilder\1.jpg","_UpdateParts")

    Zeile 23:
    Func _FTP_Upload( $server, $user, $password, $file,$FileLocal ,$FunctionToCall="")


    Frage:
    Ich gebe oben ja die Variablen ein, aber ich gebe nur einmal server und einmal password an.
    Ist es richtig, das die Variablen $serv und $server bzw. $pass und $password verwendet werden und beides ist doch das gleiche.

    Bei mir sehen die ersten Zeilen so aus:

    Spoiler anzeigen
    [autoit]


    ; Program til at uploade billeder er oprettet med AutoIt
    ; Implementering af: progandy

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

    $server = "home.dknet.net"
    $user = "crazy"
    $password = "***************" ; ase adgangskode til stjernerne brug

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

    ProgressOn("Upload","Uploading file [Cancel with F8]")
    $x = _FTP_Upload( $server, $user, $password, 'public_html/testdatei.jpg' , 'E:\testdatei.jpg')
    ProgressSet(100,"Return: " & $x & @CRLF & "Error: " & @error)
    Sleep(2000)
    ProgressOff()

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

    ProgressOn("Upload","Uploading file [Cancel with F8]")
    $x = _FTP_Upload( $server, $user, $password, 'public_html/testdatei2.jpg' , 'E:\testdatei2.jpg')
    ProgressSet(100,"Return: " & $x & @CRLF & "Error: " & @error)
    Sleep(2000)
    ProgressOff()

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

    Func _UpdateParts($percent)
    ProgressSet($percent,$percent &"%")
    If _IsPressed("77") Then Return 0
    ;~ Switch GUIGetMsg()
    ;~ Case $GUI_EVENT_CLOSE
    ;~ Return -1 ; In Upload einn Abbruch einbauen, der negative Werte als Return angibt :) dann im Haupt-Programm testen.
    ;~ Case $Cancel
    ;~ Return 0 ; bei 0 Abbruch
    ;~ EndSwitch
    Return 1 ; bei 1 Fortsetzten
    Endfunc

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

    Func _FTP_Upload( $server, $user, $password, $file,$FileLocal ,$FunctionToCall="")
    ...
    ...

    [/autoit]

    Gruß, Crazy-A.

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

  • Ja, das stimmt. Die Varablennmen im Funktionsaurf müssen nicht mit denen in der Deklaration übereinstimmen.
    Der Aufbau ist aber nicht so toll, da jedes mal die Verbindung zum Server neu hergestellt wird. Ich bin mit der FTP_Ex.au3 fast fertig, nur noch uploaden ;) Da ist das dann wie _FTPPutFile.

  • @progandy: ???

    Was ist denn nun die FTP_Ex.au3 und machst Du es so, das auch Anfängerinnen es verstehen? Also mit Erklärung für Blondi ;)

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

  • äh.. Wow..
    Da hab ich wohl echt was ins Rollen gebracht ;)
    Hätte das auch ganz gerne selbst gelöst :pinch:
    :P
    Vielen Dank, hast mir viel Zeit gespart =)

    mfg limette

    There are only 10 types of people in the world:
    Those who understand binary - and those who don't.

  • Das ist auch noch so ne Sache, wozu braucht man etwas wie einen
    'FTP-Download' ?
    Da kann man doch auch einfach 'InetGet' nehmen, mit dem 'Background'-Parameter,
    ner While-Schleife und nem FileGetSize ? ^^

    There are only 10 types of people in the world:
    Those who understand binary - and those who don't.

  • Also ich meine das ich mich mal ran setzen sollte eine GUI dafür zu schreiben.
    So das man 1-5 Dateien uploaden kann.

    Schau'n wir mal ;)

    Crazy-A

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

  • Stimmt, der FTP-download ist da ja schon integriert :) Und dafür gibt es auch schon irgendwo eine UDF mit
    @InetGetActive und @InetGetBytesRead