Jump to content

Error copying file from FTP using _FTP_FileGet()


Recommended Posts

I have code that uses calls to functions in FTPEx.au3 to copy a file to a local directory, but the copy fails.
 
The steps I took were:
_FTP_Open()
_FTP_Connect()
_FTP_FileGet()
 
The _FTP_FileGet() returns a 0 (failed) and the file is not copied.  I've tried passing the full FTP pathname and just the base filename, and I've tried inserting a call to _FTP_DirSetCurrent() just before calling _FTP_FileGet(), but nothing worked.
 
Here is my test code:
#include <FTPex.au3>

_Main()

Func _Main()
    $ret = copyFile()
    $err = @error
    ConsoleWrite("..." & @CRLF)
    ConsoleWrite("+++: $err = " & $err & ", $ret = " & $ret & @CRLF)
EndFunc   ;==>_Main

Func copyFile()
    Local $sIP, $sUsername, $sPassword, $FTPDir, $localDir, $fname, $session
    Local $err, $hConn, $from, $to, $ret

    $sIP = "xxxxxx"
    $sUsername = "xxxxx"
    $sPassword = "xxxxx"

    $FTPDir = "/Andy"
    $localDir = "C:\Temp"
    $fname = "READ2ME.txt"
    $from = $FTPDir & "/" & $fname
    $to = $localDir & "\" & $fname

    $session = open()
    If ($session == 0) Then Return (0)

    $hConn = connect($session, $sIP, $sUsername, $sPassword)
    If ($hConn == 0) Then Return (0)

    ;$ret = setcurrent($hConn, $FTPDir) ; <-- returns '1' (not a dir name, like the help doc says)
    ;If ($ret == 0) Then Return (0)

    $ret = fileget($hConn, $from, $to)
    If ($ret == 0) Then Return (0)

    If (FileExists($to)) Then
        ConsoleWrite("--> File copied OK" & @CRLF)
        Return (0)
    Else
        ConsoleWrite("--> File wasn't copied!!")
        Return (1)
    EndIf
EndFunc   ;==>copyFile

Func open()
    $session = _FTP_Open('_myFTP Control')

    $err = @error
    ConsoleWrite("+++: after  _FTP_Open(): @error = " & $err & ", $session = " & Hex($session) & @CRLF)
    If ($err <> 0) Or ($session == 0) Then
        ConsoleWrite("+++: _FTP_Open() - FAILED" & @CRLF)
        Return (0)
    Else
        ConsoleWrite("+++: _FTP_Open() - OK" & @CRLF)
        Return ($session)
    EndIf
EndFunc   ;==>open

Func connect($session, $ip, $uname, $pwd)
    $hConn = _FTP_Connect($session, $ip, $uname, $pwd)

    $err = @error
    ConsoleWrite("+++: after  _FTP_Connect(): @error = " & $err & ", $hConn = " & Hex($hConn) & @CRLF)
    If ($err <> 0) Or ($hConn == 0) Then
        ConsoleWrite("+++: _FTP_Connect() - FAILED" & @CRLF)
        Return (0)
    Else
        ConsoleWrite("+++: _FTP_Connect() - OK" & @CRLF)
        Return ($hConn)
    EndIf
EndFunc   ;==>connect

Func setcurrent($hConn, $fdir)
    $ret = _FTP_DirSetCurrent($hConn, $fdir) ; Note: returns '1' instead of the Dir name

    $err = @error
    ConsoleWrite("+++: after  _FTP_DirSetCurrent(): @error = " & $err & ", $ret = " & $ret & @CRLF)
    If ($err <> 0) Or ($ret == 0) Or ($ret == "") Then
        ConsoleWrite("+++: _FTP_DirSetCurrent() - FAILED" & @CRLF)
        Return (0)
    Else
        ConsoleWrite("+++: _FTP_DirSetCurrent() - OK" & @CRLF)
        Return ($ret)
    EndIf
EndFunc   ;==>setcurrent

Func fileget($hConn, $from, $to)
    $ret = _FTP_FileGet($hConn, $from, $to, False)
    $err = @error
    ConsoleWrite("+++: after  _FTP_FileGet(): $ret = " & $ret & ", @error = " & $err & @CRLF)
    ConsoleWrite("+++: $from = " & $from & ", $to = " & $to & @CRLF)
    If ($err <> 0) Or ($ret <> 1) Then
        ConsoleWrite("+++: _FTP_FileGet() - FAILED " & @CRLF)
        Return (0)
    Else
        ConsoleWrite("+++: _FTP_FileGet() - OK" & @CRLF)
    EndIf
EndFunc   ;==>fileget

Here is the Console output:

+++: after  _FTP_Open(): @error = 0, $session = 00CC0004
+++: _FTP_Open() - OK
+++: after  _FTP_Connect(): @error = 0, $hConn = 00CC0008
+++: _FTP_Connect() - OK
+++: after  _FTP_FileGet(): $ret = 0, @error = -1
+++: $from = /Andy/READ2ME.txt, $to = C:\Temp\READ2ME.txt
+++: _FTP_FileGet() - FAILED 
...
+++: $err = 0, $ret = 0

Any help would be appreciated.

Andy

Link to comment
Share on other sites

Try this:

#include <FTPex.au3>

_Main()

Func _Main()
    $ret = copyFile()
    $err = @error
    ConsoleWrite("..." & @CRLF)
    ConsoleWrite("+++: $err = " & $err & ", $ret = " & $ret & @CRLF)
EndFunc   ;==>_Main

Func copyFile()
    Local $sIP, $sUsername, $sPassword, $FTPDir, $localDir, $fname, $session
    Local $err, $hConn, $from, $to, $ret

    $sIP = "xxxxxx"
    $sUsername = "xxxxx"
    $sPassword = "xxxxx"

    $FTPDir = "Andy"
    $localDir = "C:\Temp"
    $fname = "READ2ME.txt"
    $from = $fname
    $to = $localDir & "\" & $fname

    $session = open()
    If ($session == 0) Then Return (0)

    $hConn = connect($session, $sIP, $sUsername, $sPassword)
    If ($hConn == 0) Then Return (0)

    $ret = setcurrent($hConn, $FTPDir) ; <-- returns '1' (not a dir name, like the help doc says)
    If ($ret == 0) Then Return (0)

    $ret = fileget($hConn, $from, $to)
    If ($ret == 0) Then Return (0)

    If (FileExists($to)) Then
        ConsoleWrite("--> File copied OK" & @CRLF)
        Return (0)
    Else
        ConsoleWrite("--> File wasn't copied!!")
        Return (1)
    EndIf
EndFunc   ;==>copyFile

Func open()
    $session = _FTP_Open('_myFTP Control')

    $err = @error
    ConsoleWrite("+++: after  _FTP_Open(): @error = " & $err & ", $session = " & Hex($session) & @CRLF)
    If ($err <> 0) Or ($session == 0) Then
        ConsoleWrite("+++: _FTP_Open() - FAILED" & @CRLF)
        Return (0)
    Else
        ConsoleWrite("+++: _FTP_Open() - OK" & @CRLF)
        Return ($session)
    EndIf
EndFunc   ;==>open

Func connect($session, $ip, $uname, $pwd)
    $hConn = _FTP_Connect($session, $ip, $uname, $pwd)

    $err = @error
    ConsoleWrite("+++: after  _FTP_Connect(): @error = " & $err & ", $hConn = " & Hex($hConn) & @CRLF)
    If ($err <> 0) Or ($hConn == 0) Then
        ConsoleWrite("+++: _FTP_Connect() - FAILED" & @CRLF)
        Return (0)
    Else
        ConsoleWrite("+++: _FTP_Connect() - OK" & @CRLF)
        Return ($hConn)
    EndIf
EndFunc   ;==>connect

Func setcurrent($hConn, $fdir)
    $ret = _FTP_DirSetCurrent($hConn, $fdir) ; Note: returns '1' instead of the Dir name

    $err = @error
    ConsoleWrite("+++: after  _FTP_DirSetCurrent(): @error = " & $err & ", $ret = " & $ret & @CRLF)
    If ($err <> 0) Or ($ret == 0) Or ($ret == "") Then
        ConsoleWrite("+++: _FTP_DirSetCurrent() - FAILED" & @CRLF)
        Return (0)
    Else
        ConsoleWrite("+++: _FTP_DirSetCurrent() - OK" & @CRLF)
        Return ($ret)
    EndIf
EndFunc   ;==>setcurrent

Func fileget($hConn, $from, $to)
    $ret = _FTP_FileGet($hConn, $from, $to, False)
    $err = @error
    ConsoleWrite("+++: after  _FTP_FileGet(): $ret = " & $ret & ", @error = " & $err & @CRLF)
    ConsoleWrite("+++: $from = " & $from & ", $to = " & $to & @CRLF)
    If ($err <> 0) Or ($ret <> 1) Then
        ConsoleWrite("+++: _FTP_FileGet() - FAILED " & @CRLF)
        Return (0)
    Else
        ConsoleWrite("+++: _FTP_FileGet() - OK" & @CRLF)
    EndIf
EndFunc   ;==>fileget
Link to comment
Share on other sites

Nope, that failed also.  I assume that you actually tried it, so that leaves my FTP credentials.  The IP address I'm using is something like this: abc.def.com, instead of like this: 10.222.12.123.  Do you think that that matters?

Link to comment
Share on other sites

I haven't tested any of the previously mentioned scripts.  Are you able to get a file list using _FTP_ListToArray or _FTP_ListToArrayEx?  I'm not clear where the script is failing--at _FTP_DirSetCurrent or at _FTP_FileGet?

#include <FTPEx.au3>
Global $sSite = "abc.def.com"
Global $sUser = "xxxxxx"
Global $sPass = "xxxxxx"
Global $sRemoteDir = "Andy" ; Could this be case-sensitive?
Global $sFile = "READ2ME.txt" ; Could this also be case-sensitive?
Global $sLocalDir = "C:\Temp\" ; This must exist before getting the file, so you may need to check if the folder exists and if not, create the folder first
Global $hOpen = _FTP_Open("My Site")
If @error Then ConsoleWrite("FTP Open Error: " & @error & @CRLF)
Global $hConnect = _FTP_Connect($hOpen, $sSite, $sUser, $sPass)
If @error Then ConsoleWrite("FTP Connect Error: " & @error & @CRLF)
_FTP_DirSetCurrent($hConnect, $sRemoteDir)
If @error Then ConsoleWrite("FTP Set Current Directory Error: " & @error & @CRLF)
_FTP_FileGet($hConnect, $sFile, $sLocalDir & $sFile)
If @error Then ConsoleWrite("FTP Get File Error: " & @error & @CRLF)
If FileExists($sLocalDir & $sFile) Then ShellExecute($sLocalDir & $sFile)
_FTP_Close($hOpen)
If @error Then ConsoleWrite("FTP Close Error: " & @error & @CRLF)
Edited by GMK
Link to comment
Share on other sites

I tried _FTP_ListToArray() in place of _FTP_FileGet() and it properly returned an array with the name of the only file in the FTP directory (READ2ME.txt).

So, I can see the names of the files on the FTP site, but _FTP_FileGet() fails.

If you look at this Console output (as I mentioned in my original post), you will see that the failure was the call to _FTP_FileGet().

+++: after  _FTP_Open(): @error = 0, $session = 00CC0004
+++: _FTP_Open() - OK
+++: after  _FTP_Connect(): @error = 0, $hConn = 00CC0008
+++: _FTP_Connect() - OK
+++: after  _FTP_FileGet(): $ret = 0, @error = -1
+++: $from = /Andy/READ2ME.txt, $to = C:\Temp\READ2ME.txt
+++: _FTP_FileGet() - FAILED 
...
+++: $err = 0, $ret = 0
Link to comment
Share on other sites

Is the FTP site you're connecting to using secure FTP (i.e. SFTP)? Because if it is, then the built in FTP UDF won't work with it.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

Well, after "uncommenting" lines 32 and 33 and substituting my own server, username, password, remote directory and file, it worked for me.  I had to comment out line 36 if I wanted to see the confirmation from lines 38-44.

Link to comment
Share on other sites

hmmm...

What if I give you my credentials (off line, of course!)?  Or do you know of an FTP site that we both can get to?  That way, I could eliminate the FTP site as the problem.

BTW: I can run GoodSync and Core FTP LE (using the same credentials) to copy my file to the came local directory and they both copy the file successfully.

Link to comment
Share on other sites

How about this?

#include <FTPex.au3>

_Main()

Func _Main()
    $ret = copyFile()
    $err = @error
    ConsoleWrite("..." & @CRLF)
    ConsoleWrite("+++: $err = " & $err & ", $ret = " & $ret & @CRLF)
EndFunc   ;==>_Main

Func copyFile()
    Local $sIP, $sUsername, $sPassword, $FTPDir, $localDir, $fname, $session
    Local $err, $hConn, $from, $to, $ret

    ;ftp://mirror.esc7.net/pub/OpenBSD/doc/obsd-faq.txt
    $sIP = "mirror.esc7.net"
    $sUsername = ""
    $sPassword = ""

    $FTPDir = "/pub/OpenBSD/doc/"
    $localDir = "C:\Temp"
    $fname = "obsd-faq.txt"
    $from = $FTPDir & "/" & $fname
    $to = $localDir & "\" & $fname

    $session = open()
    If ($session == 0) Then Return (0)

    $hConn = connect($session, $sIP, $sUsername, $sPassword)
    If ($hConn == 0) Then Return (0)

    $ret = setcurrent($hConn, $FTPDir) ; <-- returns '1' (not a dir name, like the help doc says)
    If ($ret == 0) Then Return (0)

    $ret = fileget($hConn, $from, $to)
    If ($ret == 0) Then Return (0)

    If (FileExists($to)) Then
        ConsoleWrite("--> File copied OK" & @CRLF)
        Return (0)
    Else
        ConsoleWrite("--> File wasn't copied!!")
        Return (1)
    EndIf
EndFunc   ;==>copyFile

Func open()
    $session = _FTP_Open('_myFTP Control')

    $err = @error
    ConsoleWrite("+++: after  _FTP_Open(): @error = " & $err & ", $session = " & Hex($session) & @CRLF)
    If ($err <> 0) Or ($session == 0) Then
        ConsoleWrite("+++: _FTP_Open() - FAILED" & @CRLF)
        Return (0)
    Else
        ConsoleWrite("+++: _FTP_Open() - OK" & @CRLF)
        Return ($session)
    EndIf
EndFunc   ;==>open

Func connect($session, $ip, $uname, $pwd)
    $hConn = _FTP_Connect($session, $ip, $uname, $pwd)

    $err = @error
    ConsoleWrite("+++: after  _FTP_Connect(): @error = " & $err & ", $hConn = " & Hex($hConn) & @CRLF)
    If ($err <> 0) Or ($hConn == 0) Then
        ConsoleWrite("+++: _FTP_Connect() - FAILED" & @CRLF)
        Return (0)
    Else
        ConsoleWrite("+++: _FTP_Connect() - OK" & @CRLF)
        Return ($hConn)
    EndIf
EndFunc   ;==>connect

Func setcurrent($hConn, $fdir)
    $ret = _FTP_DirSetCurrent($hConn, $fdir) ; Note: returns '1' instead of the Dir name

    $err = @error
    ConsoleWrite("+++: after  _FTP_DirSetCurrent(): @error = " & $err & ", $ret = " & $ret & @CRLF)
    If ($err <> 0) Or ($ret == 0) Or ($ret == "") Then
        ConsoleWrite("+++: _FTP_DirSetCurrent() - FAILED" & @CRLF)
        Return (0)
    Else
        ConsoleWrite("+++: _FTP_DirSetCurrent() - OK" & @CRLF)
        Return ($ret)
    EndIf
EndFunc   ;==>setcurrent

Func fileget($hConn, $from, $to)
    $ret = _FTP_FileGet($hConn, $from, $to, False, $FTP_TRANSFER_TYPE_ASCII)
    $err = @error
    ConsoleWrite("+++: after  _FTP_FileGet(): $ret = " & $ret & ", @error = " & $err & @CRLF)
    ConsoleWrite("+++: $from = " & $from & ", $to = " & $to & @CRLF)
    If ($err <> 0) Or ($ret <> 1) Then
        ConsoleWrite("+++: _FTP_FileGet() - FAILED " & @CRLF)
        Return (0)
    Else
        ConsoleWrite("+++: _FTP_FileGet() - OK" & @CRLF)
    EndIf
EndFunc   ;==>fileget
Link to comment
Share on other sites

That worked for me.  The error I was getting when I used my FTP credentials came from the _FTP_FileGet().  The transfer left the local file as Read-Only and 0 bytes, so subsequent calls failed because the file couldn't be overwritten.  I put in a file delete that cleared the Read-Only attribute before doing the delete.  I could run my test repeatedly and each time, the file name was created in my local directory, but as a Read-Only file that had a size of 0 bytes, and  _FTP_FileGet() returned a FAILURE.

I added a call to _FTP_GetLastResponseInfo($enum, $emsg) and here are the results:

$emsg = 200 Type set to I
200 PORT command successful
550 /Andy/READ2ME.txt: No such file or directory
550 /Andy/READ2ME.txt: No such file or directory
 
So I looked at the file on my FTP site and I saw that I was trying to copy a file called READ2ME.txt, but the file on my FTP server was READ2ME.TXT (same file, different letter case).
 
What a rookie mistake  :oops:  :doh:  
 
I started back at my real script where I had extracted the code into the test code I first sent out and the file name I used was for a file that actually existed on the FTP site, but when I copied a test file (READ2ME.txt) to the FTP site, I typed the destination file name in all uppercase.
 
So, I'm really sorry I took up your time on this and in the future, I'll be sure to set up a test script with all the basic stuff created correctly.
 
 
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...