Working with FTP's?

I am using VB.NET 2002 and am working in a windows form.

I am trying to figure out the most effective way of connecting to an FTP server and obtaining a list of all files, file paths, and file sizes on that server.

Couldn't someone suggest some reasources related to this? I am unable to find any.

Thanks.
frosty5656Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Éric MoreauSenior .Net ConsultantCommented:
knotonCommented:
Below you find a Class For a FTP-Client Helper class 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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.