Imports System.Runtime.InteropServices
''' <warning>DO NOT REMOVE ANY OF THIS INFORMATION.</warning>
''' <author>loyalty</author>
''' <link>http://loyaltyHF.blogspot.com</link>
''' <email>loyalty.exe@gmail.com</email>
''' <summary>FTP Class based on win32 APIs.
''' The default .NET methods for dealing with FTP, connect and disconnect eventualy with the operation so if
''' you are willing to do multiple operation then you'll connect and disconnect along with with every operation
''' For Example: My.Computer.Network.UploadFile</summary>
''' <remarks>Feel free to use this class but don't forget to give credits</remarks>
''' <Initial_Release>November 27,2012</Initial_Release>
Public Class FTPClass
#Region "Native"
'http://msdn.microsoft.com/en-us/library/windows/desktop/aa385473%28v=vs.85%29.aspx
'http://pinvoke.net/default.aspx/wininet.InternetOpen
Private Declare Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" ( _
ByVal sAgent As String, _
ByVal lAccessType As Int32, _
ByVal sProxyName As String, _
ByVal sProxyBypass As String, _
ByVal lFlags As Integer) As Int32
'http://pinvoke.net/default.aspx/wininet.InternetConnect
Private Declare Auto Function InternetConnect Lib "wininet.dll" ( _
ByVal hInternetSession As System.IntPtr, _
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 System.IntPtr) As System.IntPtr
'http://pinvoke.net/default.aspx/wininet.FtpPutFile
Private Declare Function FtpPutFile Lib "wininet.dll" Alias "FtpPutFileA" ( _
ByVal hFtpSession As IntPtr, _
ByVal lpszLocalFile As String, _
ByVal lpszRemoteFile As String, _
ByVal dwFlags As Integer, _
ByVal dwContext As Integer) As Boolean
'http://pinvoke.net/default.aspx/wininet.InternetCloseHandle
Private Declare Function InternetCloseHandle Lib "wininet.dll" ( _
ByVal hInet As IntPtr) As Boolean
'http://pinvoke.net/default.aspx/wininet.FtpCreateDirectory
<DllImport("wininet.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FtpCreateDirectory(ByVal hConnect As IntPtr, ByVal lpszDirectory As String) As Boolean
End Function
'http://pinvoke.net/default.aspx/wininet.FtpSetCurrentDirectory
Declare Function FtpSetCurrentDirectory Lib "wininet.dll" Alias _
"FtpSetCurrentDirectoryA" _
(ByVal hConnect As IntPtr, _
ByVal lpszDirectory As String) As Boolean
'http://www.pinvoke.net/default.aspx/wininet.InternetGetLastResponseInfo
Declare Function InternetGetLastResponseInfo Lib "wininet.dll" Alias "InternetGetLastResponseInfoA" _
(ByRef errorCode As Integer, _
ByVal buffer As String, _
ByRef bufferLength As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
#End Region
#Region "Declearions"
Public Delegate Sub Progress(ByVal name As String, ByVal Progress As Integer, ByVal msg As String)
Public Event Uploading(ByVal name As String)
Public Event Uploaded(ByVal name As String)
Public Event UploadFailed(ByVal name As String)
Public Event ServerResponce(ByVal info As String)
#End Region
#Region "Properties"
Private _connect As IntPtr
Private Property Connect() As IntPtr
Get
Return _connect
End Get
Set(ByVal value As IntPtr)
_connect = value
End Set
End Property
Private _hInet As IntPtr
Private Property hInet() As IntPtr
Get
Return _hInet
End Get
Set(ByVal value As IntPtr)
_hInet = value
End Set
End Property
Private _conneted As Boolean
Public Property Connected() As Boolean
Get
Return _conneted
End Get
Set(ByVal value As Boolean)
_conneted = value
End Set
End Property
Private _port As Integer = 21
Private Property Port() As Integer
Get
Return _port
End Get
Set(ByVal value As Integer)
_port = value
End Set
End Property
#End Region
#Region "Consructor"
''' <summary>
''' Creates a new instance of FTPClass and starts a new internet session
''' </summary>
''' <param name="address">address/ip of the server. Don't include the protocol</param>
''' <param name="user">Username</param>
''' <param name="pass">Password</param>
''' <param name="_port">Port Number. Default is 21</param>
Sub New(ByVal address As String, ByVal user As String, ByVal pass As String, Optional ByVal _port As Integer = 21)
Port = _port
OpenConnection(address, user, pass)
End Sub
#End Region
#Region "Private Methods"
Private Sub OpenConnection(ByVal address As String, ByVal user As String, ByVal pass As String)
hInet = InternetOpen("Internet Explorer", 1, vbNullString, vbNullString, 0)
If hInet = 0 Then
Connected = False
Else
Connect = InternetConnect(hInet, address, Port, user, pass, 1, 0, 0)
If Connect = 0 Then
Connected = False
Else
Connected = True
End If
End If
End Sub
'Private Sub CreateDirectoryStructure(ByVal dir As String)
' If Connected Then
' FtpCreateDirectory(Connect, dir.Substring(dir.LastIndexOf("\") + 1))
' For Each d In IO.Directory.GetDirectories(dir, "*", IO.SearchOption.AllDirectories)
' FtpCreateDirectory(Connect, d.Remove(0, dir.LastIndexOf("\") + 1).Replace("\", "/"))
' Next
' Else
' Throw New Exception("Not connected!")
' End If
'End Sub
Private Sub UploadDirectoryR(ByVal Folder As String, ByVal mp As String)
If Connected Then
CreateDirectory(Folder.Substring(mp.LastIndexOf("\") + 1).Replace("\", "/"))
For Each f In IO.Directory.GetFiles(Folder)
UploadFile(f, f.Substring(mp.LastIndexOf("\") + 1).Replace("\", "/"))
Next
For Each f In IO.Directory.GetDirectories(Folder)
UploadDirectoryR(f, mp)
Next
End If
End Sub
#End Region
#Region "Public Methods"
''' <summary>
''' Uploads a single file to the FTP server
''' </summary>
''' <param name="sourceFile">Path to local file</param>
''' <param name="remoteFile">Path to remote file. By default file is uploaded to current directory</param>
''' <returns>Boolean</returns>
Public Function UploadFile(ByVal sourceFile As String, Optional ByVal remoteFile As String = "") As Boolean
If Connected Then
If String.IsNullOrEmpty(remoteFile) Then remoteFile = sourceFile.Substring(sourceFile.LastIndexOf("\") + 1)
RaiseEvent Uploading(sourceFile)
If FtpPutFile(Connect, sourceFile, remoteFile, 2, 0) Then
RaiseEvent Uploaded(sourceFile)
RaiseEvent ServerResponce(GetLastResponse)
Return True
Else
RaiseEvent UploadFailed(sourceFile)
RaiseEvent ServerResponce(GetLastResponse)
Return False
End If
Else
Throw New Exception("Not connected!")
End If
End Function
''' <summary>Gets the server responce for the latest request/opeation</summary>
''' <returns>Informtion as string</returns>
Public Function GetLastResponse() As String
Dim errorCode As Integer = 0
Dim buffSize As Integer = 0
InternetGetLastResponseInfo(errorCode, vbNullString, buffSize)
Dim message As String = Space(buffSize + 1)
InternetGetLastResponseInfo(errorCode, message, buffSize)
Return message
End Function
''' <summary>Closes the current internet session</summary>
''' <returns>Boolean. Success or not.</returns>
Public Function Close() As Boolean
If Connected Then
If InternetCloseHandle(Connect) Then
InternetCloseHandle(hInet)
RaiseEvent ServerResponce(GetLastResponse)
Connected = False
Return True
Else
RaiseEvent ServerResponce(GetLastResponse)
Return False
End If
Else
Throw New Exception("Not connected!")
End If
End Function
''' <summary> Upload Multiple files to remote FTP server</summary>
''' <param name="sourceFiles">File paths as s string array</param>
''' <returns>No. of successfully uploaded files</returns>
Public Function UploadFiles(ByVal sourceFiles As String()) As Integer
If Connected Then
Dim count As Integer = 0
For Each F In sourceFiles
If UploadFile(F) Then
count += 1
End If
Next
Return count
Else
Throw New Exception("Not connected!")
End If
End Function
''' <summary> Upload Multiple files to remote FTP server with reporting </summary>
''' <param name="sourceFiles">File paths as s string array</param>
''' <param name="ProgressE">Reports progress. Progress(ByVal name As String, ByVal Progress As Integer, ByVal msg As String)</param>
''' <returns>No. of successfully uploaded files</returns>
Public Function UploadFiles(ByVal sourceFiles As String(), ByVal ProgressE As Progress) As Integer
If Connected Then
Dim count As Integer = 0
Dim Progress As Integer = 0
Dim PCE As Progress = ProgressE
For Each F In sourceFiles
PCE(F, CInt((Progress / sourceFiles.Length) * 100), "Uploading")
Progress += 1
If UploadFile(F) Then
count += 1
PCE(F, CInt((Progress / sourceFiles.Length) * 100), "Uploaded")
Else
PCE(F, CInt((Progress / sourceFiles.Length) * 100), "Upload failed")
End If
Next
Return count
Else
Throw New Exception("Not connected!")
End If
End Function
'Public Sub UploadDirectory(ByVal Folder As String)
' If Connected Then
' CreateDirectoryStructure(Folder)
' For Each f In IO.Directory.GetFiles(Folder, "*.*", IO.SearchOption.AllDirectories)
' UploadFile(f, f.Remove(0, Folder.LastIndexOf("\") + 1).Replace("\", "/"))
' Next
' Else
' Throw New Exception("Not connected!")
' End If
'End Sub
''' <summary>Uploads a directory. Uploads all the directories within that directory too.</summary>
''' <param name="Folder">Directory to be uploaded</param>
Public Sub UploadDirectory(ByVal Folder As String)
If Connected Then
UploadDirectoryR(Folder, Folder)
RaiseEvent ServerResponce(GetLastResponse)
Else
Throw New Exception("Not connected!")
End If
End Sub
''' <summary>Set the current directory of the FTP server</summary>
''' <param name="path">Directory to set as current directory</param>
''' <returns>Boolean. Success or not.</returns>
Public Function SetCurrentDirectory(ByVal path As String) As Boolean
If Connected Then
If FtpSetCurrentDirectory(Connect, path) Then
RaiseEvent ServerResponce(GetLastResponse)
Return True
Else
RaiseEvent ServerResponce(GetLastResponse)
Return False
End If
Else
Throw New Exception("Not connected!")
End If
End Function
''' <summary> Creates a directory on the FTP server </summary>
''' <param name="dir">Directory name. Remember to use "/" instead of "\"</param>
''' <returns>Boolean. Success or not.</returns>
Public Function CreateDirectory(ByVal dir As String) As Boolean
If Connected Then
If FtpCreateDirectory(Connect, dir) Then
RaiseEvent ServerResponce(GetLastResponse)
Return True
Else
RaiseEvent ServerResponce(GetLastResponse)
Return False
End If
Else
Throw New Exception("Not connected!")
End If
End Function
#End Region
End Class