Link to home
Start Free TrialLog in
Avatar of Carolinat
Carolinat

asked on

FtpGetFile error 12003-Application-defined or object-defined error.

I'm trying to use the ftpgetfile but it doesn't work. I'm using the framework 1.1.4322 and I don't know if this function doesn't work in this framework or if I have an error with the parameters. This is the code:

   Private Const FTP_TRANSFER_TYPE_ASCII = &H1
    Private Const INTERNET_FLAG_RELOAD = &H80000000

 Private Declare Function InternetConnect Lib "wininet.dll" Alias "InternetConnectA" _
    (ByVal hInternetSession As Integer, ByVal sServerName As String, _
    ByVal nServerPort As Integer, ByVal sUsername As String, _
    ByVal sPassword As String, ByVal lService As Integer, _
    ByVal lFlags As Integer, ByVal lContext As Integer) As Integer

        Dim blnRC As Long

         blnRC = FtpGetFile(lngINetConn, "inicio.html", _
                                "c:\WorkProjVPC\files\test1.txt", _
                                False, INTERNET_FLAG_RELOAD, FTP_TRANSFER_TYPE_ASCII, 0)

Now I geting this error: 12003-Application-defined or object-defined error. How do you guys think that I can solve this? thanks Carol
Avatar of knoton
knoton

Have you checked if you have a working connection ?
The value of lngINetConn should be > 0 for you to have a working connection made....

Below you find a Class For a FTP-Client I made.
A working example and source you find at:
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=2878&lngWId=10


'******Created 2004-10-16 by Kenneth Hedman aka Knoton******'

Imports System.Runtime.InteropServices
''' -----------------------------------------------------------------------------
''' <summary>
''' KFTP is a FTP Client helper class made for developers.
''' </summary>
''' <remarks>
''' </remarks>
''' <history>
'''      [Knoton]     2004-10-16     Created
''' </history>
''' -----------------------------------------------------------------------------
Namespace KFTP
    ''' -----------------------------------------------------------------------------
    ''' Project      : KFTP
    ''' Class      : KFTP.FTP
    '''
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' FTP Client class.
    ''' Helperclass for downloading/uploading directories/files on a FTP-Server.
    ''' </summary>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    '''      [Knoton]     2005-11-18     Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Class FTP
        Private Const FTP_TRANSFER_TYPE_UNKNOWN = &H0
        Private Const FTP_TRANSFER_TYPE_BINARY = &H2
        Private Const FTP_TRANSFER_TYPE_ASCII = &H1
        Private Const INTERNET_OPEN_TYPE_DIRECT = 1
        Private Const INTERNET_SERVICE_FTP = 1
        Private Const INTERNET_FLAG_PASSIVE = &H8000000
        Private Const FILE_ATTRIBUTE_READONLY = &H1
        Private Const FILE_ATTRIBUTE_HIDDEN = &H2
        Private Const FILE_ATTRIBUTE_SYSTEM = &H4
        Private Const FILE_ATTRIBUTE_DIRECTORY = &H10
        Private Const FILE_ATTRIBUTE_ARCHIVE = &H20
        Private Const FILE_ATTRIBUTE_NORMAL = &H80
        Private Const FILE_ATTRIBUTE_TEMPORARY = &H100
        Private Const FILE_ATTRIBUTE_COMPRESSED = &H800
        Private Const FILE_ATTRIBUTE_OFFLINE = &H1000

        Private Declare Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" (ByVal sAgent As String, ByVal lAccessType As Int32, ByVal ByValsProxyName As String, ByVal sProxyBypass As String, ByVal lFlags As Int32) As Int32
        Private Declare Function InternetConnect Lib "wininet.dll" Alias "InternetConnectA" (ByVal hInternetSession As Int32, ByVal sServerName As String, ByVal nServerPort As Integer, ByVal sUserName As String, ByVal sPassword As String, ByVal lService As Int32, ByVal lFlags As Int32, ByVal lContext As Int32) As Int32
        Private Declare Function InternetCloseHandle Lib "wininet.dll" (ByVal hInet As Int32) As Int32
        Private Declare Function InternetGetLastResponseInfo Lib "wininet.dll" Alias "InternetGetLastResponseInfoA" (ByRef lpdwError As Int32, ByVal lpszBuffer As String, ByRef lpdwBufferLength As Int32) As Boolean

        Private Declare Function FtpSetCurrentDirectory Lib "wininet.dll" Alias "FtpSetCurrentDirectoryA" (ByVal hFtpSession As Int32, ByVal lpszDirectory As String) As Boolean
        Private Declare Function FtpGetCurrentDirectory Lib "wininet.dll" Alias "FtpGetCurrentDirectoryA" (ByVal hFtpSession As Int32, ByVal lpszCurrentDirectory As String, ByVal lpdwCurrentDirectory As Int32) As Int32
        Private Declare Function FtpCreateDirectory Lib "wininet.dll" Alias "FtpCreateDirectoryA" (ByVal hFtpSession As Int32, ByVal lpszDirectory As String) As Boolean
        Private Declare Function FtpRemoveDirectory Lib "wininet.dll" Alias "FtpRemoveDirectoryA" (ByVal hFtpSession As Int32, ByVal lpszDirectory As String) As Boolean
        Private Declare Function FtpDeleteFile Lib "wininet.dll" Alias "FtpDeleteFileA" (ByVal hFtpSession As Int32, ByVal lpszFileName As String) As Boolean
        Private Declare Function FtpRenameFile Lib "wininet.dll" Alias "FtpRenameFileA" (ByVal hFtpSession As Int32, ByVal lpszExisting As String, ByVal lpszNew As String) As Boolean
        Private Declare Function FtpPutFile Lib "wininet.dll" Alias "FtpPutFileA" (ByVal hFtpSession As Int32, ByVal lpszLocalFile As String, ByVal lpszRemoteFile As String, ByVal dwFlags As Int32, ByVal dwContext As Int32) As Boolean
        Private Declare Function FtpGetFile Lib "wininet.dll" Alias "FtpGetFileA" (ByVal hConnect As Int32, ByVal lpszRemoteFile As String, ByVal lpszNewFile As String, ByVal fFailIfExists As Int32, ByVal dwFlagsAndAttributes As Int32, ByVal dwFlags As Int32, ByRef dwContext As Int32) As Boolean
        Private Declare Auto Function FtpFindFirstFile Lib "wininet.dll" Alias "FtpFindFirstFileA" (ByVal hFtpSession As Int32, ByVal lpszSearchFile As String, ByRef lpFindFileData As WIN32_FIND_DATA, ByVal dwFlags As Int32, ByVal dwContent As Int32) As Int32
        Private Declare Auto Function InternetFindNextFile Lib "wininet.dll" Alias "InternetFindNextFileA" (ByVal hFind As Int32, ByRef lpvFindData As WIN32_FIND_DATA) As Int32
        Private Declare Auto Function FileTimeToSystemTime Lib "kernel32" (ByRef lpFileTime As FILETIME, ByRef lpSystemTime As SYSTEMTIME) As Long
        Private Declare Auto Function FileTimeToLocalFileTime Lib "kernel32" (ByRef lpFileTime As FILETIME, ByRef lpLocalFileTime As FILETIME) As Long
        Private Declare Function SystemTimeToVariantTime Lib "oleaut32" (ByRef lpSystemTime As SYSTEMTIME, ByRef pvTime As Date) As Long


        Private lngInternetSession As Int32
        Private lngFTPSession As Int32
        <MarshalAs(UnmanagedType.LPTStr)> Private strErr As String
        Private mTransferType As FileTransferType = FileTransferType.ftpBinary
        Public Event LastResponse(ByVal strResponse As String)
        Const MAX_PATH = 260
        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' Enum FileTransferType Holds Constants for the FTP Transfertypes
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        '''      [Knoton]     2005-11-18     Created
        ''' </history>
        ''' -----------------------------------------------------------------------------
        Public Enum FileTransferType
            ftpUnknown = FTP_TRANSFER_TYPE_UNKNOWN
            ftpAscii = FTP_TRANSFER_TYPE_ASCII
            ftpBinary = FTP_TRANSFER_TYPE_BINARY
        End Enum
        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' Enum ConnectionModes holds constants for FTP connectionTypes
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        '''      [Knoton]     2005-11-18     Created
        ''' </history>
        ''' -----------------------------------------------------------------------------
        Public Enum ConnectionModes
            Active = 0
            Passive = INTERNET_FLAG_PASSIVE
        End Enum

        Public Structure SYSTEMTIME
            Public wYear As Int32
            Public wMonth As Int32
            Public wDayOfWeek As Int32
            Public wDay As Int32
            Public wHour As Int32
            Public wMinute As Int32
            Public wSecond As Int32
            Public wMilliseconds As Int32
        End Structure

        Public Structure FILETIME
            Public dwLowDateTime As Int32
            Public wHighDateTime As Int32
        End Structure

        Private Structure WIN32_FIND_DATA
            Dim dwFileAttributes As Integer
            Dim ftCreationTime As FILETIME
            Dim ftLastAccessTime As FILETIME
            Dim ftLastWriteTime As FILETIME
            Dim nFileSizeHigh As Integer
            Dim nFileSizeLow As Integer
            Dim dwReserved0 As Integer
            Dim dwReserved1 As Integer
            <VBFixedString(MAX_PATH), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=MAX_PATH)> Public cFileName As String
            <VBFixedString(14), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=14)> Public cAlternate As String
        End Structure

        'Public Structure FileData
        '    Public Filename As String
        '    Public FileDate As DateTime
        'End Structure

        Public Property TransferType() As FileTransferType
            Get
                Return mTransferType
            End Get
            Set(ByVal Value As FileTransferType)
                mTransferType = Value
            End Set
        End Property
        'Connect to the server, return true if all went well
        Public Function ConnectToServer(ByVal Server As String, Optional ByVal Port As Int32 = 21, Optional ByVal ConnectionMode As ConnectionModes = ConnectionModes.Active, Optional ByVal Username As String = "", Optional ByVal Password As String = "") As Boolean
            Dim blnRet As Boolean
            Try
                'Close the connection to be on the safe side
                CloseConnection()

                If Username = "" Then Username = "Anonymous@Anonymous.com"

                lngInternetSession = InternetOpen("FTPPUT", INTERNET_OPEN_TYPE_DIRECT, vbNullString, vbNullString, 0)

                If lngInternetSession <> 0 Then
                    lngFTPSession = InternetConnect(lngInternetSession, Server, Port, Username, Password, INTERNET_SERVICE_FTP, ConnectionMode, 0)
                    If lngFTPSession <> 0 Then blnRet = True
                End If

                Return blnRet
            Catch ex As Exception
                Throw New Exception(ex.Message, ex)
            Finally
                GetLastInternetResponse()
            End Try
        End Function

        'Close the connection
        Public Sub CloseConnection()
            If lngFTPSession <> 0 Then InternetCloseHandle(lngFTPSession)
            If lngInternetSession <> 0 Then InternetCloseHandle(lngInternetSession)
        End Sub

        'Put a file on the current directory on the server
        Public Function PutFile(ByVal LocalFilePath As String, ByVal RemoteFilename As String) As Boolean
            Try
                Return FtpPutFile(lngFTPSession, LocalFilePath, RemoteFilename, TransferType, 0)
            Catch ex As Exception
                Throw New Exception(ex.Message, ex)
            Finally
                GetLastInternetResponse()
            End Try
        End Function

        'Get a file from the current directory
        Public Function GetFile(ByVal LocalFilePath As String, ByVal RemoteFilename As String) As Boolean
            Try
                If Not LocalFilePath.EndsWith("\") Then LocalFilePath &= "\"
                Return FtpGetFile(lngFTPSession, RemoteFilename, LocalFilePath & RemoteFilename, False, 0, TransferType, 0)
            Catch ex As Exception
                Throw New Exception(ex.Message, ex)
            Finally
                GetLastInternetResponse()
            End Try
        End Function

        'Delete a file from the current directory
        Public Function DeleteFile(ByVal strFile As String) As Boolean
            Try
                Return FtpDeleteFile(lngFTPSession, strFile)
            Catch ex As Exception
                Throw New Exception(ex.Message, ex)
            Finally
                GetLastInternetResponse()
            End Try
        End Function

        'Rename a file in the current directory
        Public Function RenameFile(ByVal oldFileName As String, ByVal NewFileName As String) As Boolean
            Try
                Return FtpRenameFile(lngFTPSession, oldFileName, NewFileName)
            Catch ex As Exception
                Throw New Exception(ex.Message, ex)
            Finally
                GetLastInternetResponse()
            End Try
        End Function

        'Create a subdirectory in the current directory
        Public Function CreateDirectory(ByVal DirectoryName As String) As Boolean
            Try
                Return FtpCreateDirectory(lngFTPSession, DirectoryName & Chr(0))
            Catch ex As Exception
                Throw New Exception(ex.Message, ex)
            Finally
                GetLastInternetResponse()
            End Try
        End Function

        'Remove a directory
        Public Function RemoveDirectory(ByVal DirectoryName As String) As Boolean
            Try
                Return FtpRemoveDirectory(lngFTPSession, DirectoryName)
            Catch ex As Exception
                Throw New Exception(ex.Message, ex)
            Finally
                GetLastInternetResponse()
            End Try
        End Function

        'Get a list of files from the current directory
        Public Function GetFileList() As ArrayList
            Dim pData As WIN32_FIND_DATA, hFind As Int32, lRet As Int32
            Dim Filename As String
            Dim ret As New ArrayList
            Dim FilData As New FTPFileData

            Try
                pData.cAlternate = New String(Chr(0), 14)

                pData.cFileName = New String(Chr(0), MAX_PATH)
                'Find the first file
                hFind = FtpFindFirstFile(lngFTPSession, "*.*", pData, 0, 0)
                'If no file exist exit
                If hFind = 0 Then Exit Function

                If pData.dwFileAttributes <> FILE_ATTRIBUTE_DIRECTORY Then

                    'Check the first file and if valid add it to the array to be  returned()
                    Filename = Left(pData.cFileName.ToString, pData.cFileName.Length)
                    If Filename <> "System Volume Information" And Filename <> "RECYCLER" Then
                        FilData.Filename = Filename
                        FilData.Filedate = FileTime2SystemTime(pData.ftLastWriteTime)
                        ret.Add(FilData)
                    End If
                End If
                Do

                    pData.cFileName = New String(Chr(0), MAX_PATH)

                    'Find next file
                    lRet = InternetFindNextFile(hFind, pData)
                    'If there is no file exit
                    If lRet = 0 Then Exit Do

                    If pData.dwFileAttributes <> FILE_ATTRIBUTE_DIRECTORY Then
                        'Check the file and if valid add it to the array to be returned()
                        Filename = Left(pData.cFileName.ToString, pData.cFileName.Length)
                        FilData.Filename = Filename
                        FilData.Filedate = FileTime2SystemTime(pData.ftLastWriteTime)
                        ret.Add(FilData)
                    End If
                Loop
                'Close the handle
                InternetCloseHandle(hFind)

                'If files are found return the array, else return nothing
                Return ret
            Catch ex As Exception
                Throw New Exception(ex.Message, ex)
            End Try
        End Function

        'Get a list of subdirectories of current directory
        Public Function GetDirectoryList() As ArrayList
            Dim pData As WIN32_FIND_DATA, hFind As Int32, lRet As Int32
            Dim Filename As String
            Dim ret As New ArrayList

            Try
                'add .. to the array, .. is the command to go back one directory
                'ret.Add("..")

                pData.cAlternate = New String(Chr(0), 14)

                pData.cFileName = New String(Chr(0), MAX_PATH)

                'Find the first file
                hFind = FtpFindFirstFile(lngFTPSession, "*.*", pData, 0, 0)
                'If there is no file exit
                If hFind = 0 Then
                    Return ret
                    Exit Function
                End If

                If pData.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY Then
                    'Check the file and if it is a directory add it to the array to be returned
                    Filename = Left(pData.cFileName.ToString, pData.cFileName.Length)
                    If Filename <> "System Volume Information" And Filename <> "RECYCLER" And Filename <> ".." Then
                        ret.Add(Filename)
                    End If
                End If

                Do
                    pData.cFileName = New String(Chr(0), MAX_PATH)

                    'Find next file
                    lRet = InternetFindNextFile(hFind, pData)
                    'If there is no file exit
                    If lRet = 0 Then Exit Do

                    If pData.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY Then
                        'Check the file and if it is a directory add it to the array to be returned
                        Filename = Left(pData.cFileName.ToString, pData.cFileName.Length)
                        If Filename <> "System Volume Information" And Filename <> "RECYCLER" And Filename <> ".." Then
                            ret.Add(Filename)
                        End If
                    End If
                Loop
                'Close the handle
                InternetCloseHandle(hFind)

                'Return the array with directories
                Return ret
            Catch ex As Exception
                Throw New Exception(ex.Message, ex)
            End Try
        End Function

        'Move to choosen directory
        Public Function SetWorkingDir(ByVal WorkingDir As String) As Boolean
            Try
                Return FtpSetCurrentDirectory(lngFTPSession, WorkingDir)
            Catch ex As Exception
                Throw New Exception(ex.Message, ex)
            Finally
                GetLastInternetResponse()
            End Try
        End Function
        Public Function MoveDirectoryBack() As Boolean
            Try
                Return FtpSetCurrentDirectory(lngFTPSession, "..")
            Catch ex As Exception
                Throw New Exception(ex.Message, ex)
            Finally
                GetLastInternetResponse()
            End Try
        End Function
        'Get last response (error or info), triggers event and could also be called if events is not to be used
        Public Function GetLastInternetResponse() As String
            Dim lErr As Int32
            Dim l As Int32
            Try
                InternetGetLastResponseInfo(lErr, strErr, l)

                strErr = New String(Chr(0), l + 1)
                InternetGetLastResponseInfo(lErr, strErr, l)
                RaiseEvent LastResponse(strErr.ToString)

                Return strErr.ToString

            Catch ex As Exception
                Throw New Exception(ex.Message, ex)
            End Try
        End Function

        'Make sure to close down the connection if there is one
        Protected Overrides Sub Finalize()
            CloseConnection()
            MyBase.Finalize()
        End Sub

        Private Function FileTime2SystemTime(ByRef FileT As FILETIME) As Date
            Dim SysTime As New SYSTEMTIME
            FileTimeToLocalFileTime(FileT, FileT)
            FileTimeToSystemTime(FileT, SysTime)
            Dim d As DateTime
            SystemTimeToVariantTime(SysTime, d)
            Return d
        End Function
    End Class

    Public Class FTPFileData
        Dim mFilename As String
        Dim mFiledate As DateTime
        Public Property Filename() As String
            Get
                Return mFilename
            End Get
            Set(ByVal Value As String)
                mFilename = Value
            End Set
        End Property
        Public Property Filedate() As DateTime
            Get
                Return mFiledate
            End Get
            Set(ByVal Value As DateTime)
                mFiledate = Value
            End Set
        End Property
    End Class
End Namespace
Avatar of Carolinat

ASKER

Thanks for your answer.
I copied the exact code to my application but it still shows the same error

122-Application-defined or object-defined error.

I checked the working connection and these are the values:
lngInternetSession: 13369348
lngFTPSession: 13369352

I noticed that the program creates the file and it remains for a while with 0 bytes and then it disappeared when it shows the error.

I'm calling the function like this

blnRC = GetFile("c:\WorkProjVPC\Files\", "inicio.html")

Is this correct or what else can I do???? :(
Carol
What kind of FTP-Server are you trying to connect to ?
Could be that it is not standard (MS) protocol.
Try the same code on another server.

Also try to declare KFTP.FTP WithEvents and check the returnvalue
in event LastResponse.
You could write down all returnvalues in that event to a Textbox or something.
Hi, I checked the server which I'm connected to and that one is a Linux Server. Do you think that this is going to work?
Thanks
Carol
Well, I have tried it on several FTP-servers running on several systems like windows, linux,unix
And it has worked.
Although I know that wininet is known to not work on all servers, but most of them will work.
I have never yet encounter a server that doesn´t work.

You really should check the return value from InternetGetLastResponseInfo API.
In my code I have wrapped it to be a event that is triggered on all functions.

Instaniate kftp.ftp withevents and in the event LastRespone check the value what it says when
you get your error. It will say more than the windows error message.
Hi, Knoton,
Thanks for your answer. I'm still testing the last option that you recomended me with the  InternetGetLastResponseInfo API and now I have received a lot more information about the connection but I'm using a free ftp account just for testing but it doesn't work well. Do you know any website where I can create a ftp account and test download a file while I get the real account from my company.

Thanks Carol
An open FTP-Server that you can login in anonymous is ftp.sunet.se
FTP: ftp.sunet.se
User: anonymous
Pass: PutYourEmailadressHere
I think that server is running some BSD variant (Unix type)
I got this error, what do you think is happening?

Get Last Response-->220 Welcome to ftp.sunet.se
331 Any password will work
230 Any password will work
200 TYPE is now 8-bit binary
200 PORT command successful
213 598694917
425 Could not open data connection to port 5001: Connection timed out

thanks
Carol
ASKER CERTIFIED SOLUTION
Avatar of knoton
knoton

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you Knoton, it works perfect.

Carol
I am glad it worked out for you.
If you are interested in what happens behind you can read about
the difference between Active and Passive FTP here: http://slacksite.com/other/ftp.html