Transfering Files With The Internet Transfer Control
Posted: 2002-06-01
By: ArchiveBot
Viewed: 84
Filed Under:
No attachments for this post
Thanks to the Internet's ever-increasing prominence in our world, we developers are constantly finding new and better ways to take advantage of its capabilities. Frequently, that means finding new ways to perform tasks on the Internet - pushing the limits to do something that hasn't been done before. At other times, we must find alternate paths to take advantage of functionality that's existed for years, such as file transfers using the File Transfer Protocol (FTP). FTP gives us the ability to send or receive all sorts of files across the Internet. Web browsers use underlying FTP functionality when downloading files. We can employ that same functionality in our Visual Basic applications to transfer files across the Internet or intranet by using the Microsoft Internet Transfer Control.
Original Author: Max - Demian Net
Code
A Look At The Sample Project Figure A: Our sample application looks like this at design time. We'll also use the status bar control that ships with VB to display The sample application lets users transfer files by dragging them from Using The Control The Internet Transfer Control provides fairly extensive capabilities for You can open the Object Browser (by pressing [F2]) to examine all the Table A: Selected properties, methods, and events Performing Transfers To perform FTP transfers, you must follow a few basic steps. First, you Inet1.URL = txtURL Inet1.UserName = txtUsername Since we're going to be dealing strictly with FTP connections, we'll set Inet1.Protocol = icFTP Executing Gets Things Done You'll use the Execute method to send all commands to the FTP site through Inet1.Execute URL, Operation, Data, _ Asynchronous Processing Our discussion of the asynchronous approach would be incomplete without Inet1.Execute txtURL, "get MyFile.txt" Sub Inet1.StateChanged(ByVal State As Integer) Creating The Sample Project Table B: Controls to add to the form As the name implies, the Connect button will connect to the designated Public Sub cmdConnect_Click() Once we have the list of files, we can let the user upload files to (or Similarly, if you want to upload a file to the FTP site (assuming you 1. Use relative paths when specifying local files (which is the option we 2. Place quotation marks (Chr(34)) around the full path and filename 3. Use the 8.3-character directory name 4. Don't allow spaces in directory names. With a little work, our application can allow the user to select multiple Known Bugs And Issues Fortunately, Microsoft is aware of this conflict (see the Microsoft In the SP2 version of the control, you can't log in to any server, other Finally, Microsoft released Service Pack 3 (http://msdn.microsoft.com/vstudio/sp/vs6sp3/default.asp) Code For Core Functionality Add the following to a form: Private Const ftpDIR As Integer = 0 Private Sub cmdConnect_Click() Code For Core Functionality Part 2 'Continued: Public Function GetFiles(sFileList As String) As Public Function PutFiles(sFileList As String) As Code For Core Functionality Part 3 'Continued: Private Sub _ Conclusion As the Internet's importance grows in our daily lives, we must make our
status information about the connection. To add the status-bar control to
your application, choose the Project | Components... menu item, then select
Microsoft Windows Common Controls 5.0 and click OK.
one list box to the other. Although this feature is optional, it's very
user-friendly. The sample code found in Listing A shows you the steps to
implement this drag-and-drop feature--pay particular attention to the
MouseDown, MouseUp, and DragDrop events. We'll examine how those transfers
are performed throughout the rest of this article.
transferring data across the Internet, in the form of either Web pages or
files. For our purposes, we'll concentrate on file transfers and leave the
rest for another article. The control resides in the MSINET.OCX file. To
load the control into your VB toolbox, choose Project | Components.... Next,
find the Microsoft Internet Transfer Control 5.0 control, select it by
placing an X beside it, then click OK. Now, add the control to your project
form. Note that the control will appear as a button and won't be visible at
runtime.
properties, methods, events, and built-in constants available through this
code. In addition to the control's help file, this information makes an
excellent reference. For this article, we'll focus on the small set of
available properties and methods listed in Table A.
Properties
Description
Password
The password you use when connecting with the FTP
server.
StillExecuting
Specifies whether a command is still being processed.
URL
The URL of the FTP server.
Username
User name to use to log into the FTP server.
Methods
Description
Execute
Initiates an asynchronous command/connection.
GetChunk
Reads data from the buffer.
OpenURL
Initiates a synchronous command/connection.
Events
Description
StateChanged
Fires whenever the control state has changed, for
example, when a response is received from the FTP server.
define the FTP server you want to attach to. You can specify the FTP site in
two ways: using the RemoteHost and RemotePort properties or
via the URL property. For simplicity's sake, we'll use the URL
property:
You also must specify the user name and password you'll provide. Many FTP
sites allow anonymous connections. In those cases, the user name anonymous
will work with any password you like, although most FTP sites ask you to
provide your E-mail address, as well. Here's the syntax:
Inet1.Password = txtPassword
Setting the URL property will clear the Username and Password
properties. So, be sure to set the URL first, then specify the user name and
password.
the Protocol property accordingly, as follows:
We'll want to execute these commands when we make our first connection to
the FTP server. We use the cmdConnect command button to establish this
connection, so the code will go to the server. At the same time, when we
make this first FTP connection, we'll also retrieve the list of files
available on the FTP server. We'll see how to do this next.
the control. The syntax of the Execute method is
RequestHeaders
However, when performing FTP commands, we'll only use the URL and Operation
parameters. The others have no meaning for us--they're used in other
processes. You send all FTP commands in the Operation parameter; they take
the syntax command [file1 [file2]]. The help file for the Internet Transfer
Control includes a list of valid FTP commands under the Execute page. We'll
focus on a few of these commands in the rest of this article.
are asynchronous. This means that when you tell the control to
perform an operation, it starts the operation but returns control back to
the application. The control will handle all communications back and forth,
based on the properties and commands you've given it. When the operation is
completed, the control will notify the application. If you use the OpenURL
method, the control makes a synchronous connection and executes the
command. However, control doesn't return until the command finishes
executing. This more straightforward approach is somewhat simpler to
program. Since the asynchronous approach is more flexible--and therefore
preferable--we'll use it exclusively here.
mentioning the StillExecuting property. This property identifies when
the control is in the middle of performing some operation. If you need to
perform an operation that requires several commands, you'll start the first
command, loop until the control has stopped processing the command (i.e., StillExecuting
is False), then move on to the next operation, as follows:
Do
DoEvents
Loop While Inet1.StillExecuting
In event-driven programming, we want to be able to react when the operation
is complete. We'll use the StateChanged event to provide this functionality.
Specifically, we'll look for the new State of the control to be
icResponseCompleted. It may be useful to set a variable, such as iLastFTP,
to store a value signifying which FTP command executed last. Then you can
test that variable in the StateChanged event to determine what command
completion you're reacting to, with the lines:
Select Case State
Case icResponseCompleted
`put your code here
End Select
End Sub
Of course, the State parameter can hold a number of other values as well. We
show these in the full code listing, found in Listing A. You can also check
the help file for all these values. Now, let's build our FTP application.
that shown in Figure A. As you can see, the form should include TextBox
controls for the target URL, user name, and password. You'll also need to
provide a way to display both local and remote files. Our example uses the
DirListBox, DriveListBox, and FileListBox controls for the local files, and
a standard ListBox control to display the remote files. Finally, you must
add a CommandButton to establish the initial connection. After that, our
work with the list boxes will be complete. Table B shows the controls to add
to the form, as well as some key properties.
Control
Property
Setting
Form
Caption
File Transfer
TextBox
Name
txtURL
TextBox
Name
txtUserName
TextBox
Name
txtPassword
DriveListBox
Name
drvLocal
DirListBox
Name
dirLocal
FileListBox
Name
filLocal
ListBox
Name
lstRemoteFiles
CommandButton
Name
cmdConnect
Caption
Connect
FTP site and retrieve a list of files. To accomplish this, put the following
code in the cmdConnect_Click event:
Inet1.URL = txtURL
Inet1.UserName = txtUserName
Inet1.Password = txtPassword
Inet1.Protocol = icFTP
`Use constant to identify that
`we're getting a directory listing.
`We'll use it in the
`Inet1_StateChanged Event.
iLastFTP = ftpDIR
Inet1.Execute Inet1.URL, "DIR"
End Sub
The first time we use the Execute method, we establish a connection between
the user machine and the FTP site. Executing the Dir command will place a
list of files in the control's buffer. To retrieve them from the buffer,
we'll use the GetChunk method. GetChunk requires one parameter that
specifies the maximum amount of data (in bytes) that we'll retrieve. We
specify an amount and keep looping until we've emptied out the buffer. The
result is a string of filenames, separated by a carriage return and line
feed (vbCrLf). We can then display the list of files however we want. We
wrote the function ShowRemoteFileList() in Listing A to load the file list
into a list box.
download files from) the FTP site. Since downloading files is more common,
let's consider this example first. We download files by executing the FTP
command Get. The syntax of the command is Get file1 file2, where file1
is the name of the file on the FTP site and file2 is the name you
want the file to have locally. File2 can include path information as well.
The GetFiles() function in Listing A demonstrates how to issue the command
and retrieve the file.
have write privileges at the site), you use the FTP command Put. The syntax
of the command is Put file1 file2, where file1 is the local filename
(which can include the path) and file2 is the name the file will have
on the FTP site. The PutFiles() function in Listing A demonstrates this
process. Please note that you'll have a problem to work around. The FTP
Command Line doesn't allow spaces in the filename or path. To solve this
problem, you can take one of the following steps:
used in the sample program).
(such as C:My FTP FilesTestFile.txt) in the ftp command.
files to transfer in one operation. Of course, the application will need to
issue an Execute command for each transfer. Then, we must test the StillExecuting
property to determine whether the control has finished executing that
command. Once it's complete, we can loop back and send the command again for
the second file. We can continue this process for as many files as
necessary.
of the control. These issues vary depending on which version you're using.
In the version that ships with VB 5 (version 5.00.3714), the control sends
all filenames as uppercase when you're sending or receiving files. If you're
hitting an Internet Information Server (IIS) using NT/DOS file settings,
case doesn't matter, since the filenames aren't case-sensitive. However, if
you're hitting a UNIX server, it's extremely important, since UNIX filenames
are case-sensitive. The result is that any files you send will be
named in all uppercase, and you won't be able to retrieve files that have
lowercase letters in their names.
Knowledge Base article support.microsoft.com/support/kb/articles/Q168/7/66.asp
for more information) and has corrected it in Service Pack 2 for Visual
Studio. However, the SP2 control (version 5.01.4319) introduces an even
worse problem.
than a strictly anonymous server (such as ftp://ftp.microsoft.com).
User names and passwords are sent incorrectly to the FTP server. (See the
Microsoft Knowledge Base article support.microsoft.com/support/kb/articles/Q173/2/65.asp
for more details.)
in early December 1997, correcting these problems.
Private Const ftpPUT As Integer = 1
Private Const ftpGET As Integer = 2
Private Const ftpDEL As Integer = 3
Private iLastFTP As Integer
On Error GoTo ConnectError
Inet1.URL = txtURL
Inet1.UserName = txtUserName
Inet1.Password = txtPassword
Inet1.Protocol = icFTP
iLastFTP = ftpDIR
Inet1.Execute Inet1.URL, "DIR"
End Sub
Private Sub Inet1_StateChanged(ByVal _
State As Integer)
Select Case State
Case icNone
sbFTP.Panels("status").Text = ""
Case icResolvingHost
sbFTP.Panels("status").Text
=
"Resolving Host"
Case icHostResolved
sbFTP.Panels("status").Text _
= "Host
Resolved"
Case icConnecting
sbFTP.Panels("status").Text _
=
"Connecting..."
Case icConnected
sbFTP.Panels("status").Text _
=
"Connected!"
Case icRequesting
sbFTP.Panels("status").Text _
=
"Requesting..."
Case icRequestSent
sbFTP.Panels("status").Text _
= "Request
Sent"
Case icReceivingResponse
sbFTP.Panels("status").Text _
=
"Receiving Response..."
Case icResponseReceived
sbFTP.Panels("status").Text _
=
"Response Received!"
Case icDisconnecting
sbFTP.Panels("status").Text _
=
"Disconnecting..."
Case icDisconnected
sbFTP.Panels("status").Text _
=
"Disconnected"
Case icError
sbFTP.Panels("status").Text _
= "Error!
" & Trim(CStr( _
Inet1.ResponseCode)) & _
": "
& Inet1.ResponseInfo
Case icResponseCompleted
sbFTP.Panels("status").Text _
=
"Response Completed!"
ReactToResponse iLastFTP
End Select
End Sub
Public Function _
ReactToResponse(ByVal _
iLastCommand As Integer) As Long
Select Case iLastCommand
Case ftpDIR
ShowRemoteFileList
Case ftpPUT
MsgBox
"File Sent from " & CurDir()
Case ftpGET
MsgBox
"File Received "& "in " & CurDir()
Case ftpDEL
End Select
End Function
Public Function ShowRemoteFileList() As Long
Dim sFileList As String
Dim sTemp As String
Dim p As Integer
sTemp = Inet1.GetChunk(1024)
Do While Len(sTemp) > 0
DoEvents
sFileList = sFileList & sTemp
sTemp = Inet1.GetChunk(1024)
Loop
lstRemoteFiles.Clear
Do While sFileList > ""
DoEvents
p = InStr(sFileList, vbCrLf)
If p > 0 Then
lstRemoteFiles.AddItem
Left(sFileList, p - 1)
If
Len(sFileList) > (p + 2) Then
sFileList = Mid(sFileList, p + 2)
Else
sFileList = ""
End If
Else
lstRemoteFiles.AddItem sFileList
sFileList
= ""
End If
Loop
End Function
Long
Dim sFile As String
Dim sTemp As String
Dim p As Integer
iLastFTP = ftpGET
sTemp = sFileList
Do While sTemp > ""
DoEvents
p = InStr(sTemp, "|")
If p Then
sFile =
Left(sTemp, p - 1)
sTemp =
Mid(sTemp, p + 1)
Else
sFile =
sTemp
sTemp =
""
End If
Inet1.Execute Inet1.URL,
"GET " & sFile & _
"
" & sFile
'wait until this execution is done
`before going to next file
Do
DoEvents
Loop Until Not _
Inet1.StillExecuting
Loop
iLastFTP = ftpDIR
Inet1.Execute Inet1.URL, "DIR"
End Function
Long
Dim sFile As String
Dim sTemp As String
Dim p As Integer
iLastFTP = ftpPUT
sTemp = sFileList
Do While sTemp > ""
DoEvents
p = InStr(sTemp, "|")
If p Then
sFile =
Left(sTemp, p - 1)
sTemp =
Mid(sTemp, p + 1)
Else
sFile =
sTemp
sTemp =
""
End If
Inet1.Execute Inet1.URL,
"PUT" & sFile & _
"
" & sFile
'wait until this execution is done
`before going to next file
Do
DoEvents
Loop Until Not
Inet1.StillExecuting
Loop
iLastFTP = ftpDIR
Inet1.Execute Inet1.URL, "DIR"
End Function
Private Sub dirLocal_Change()
filLocal.Path = dirLocal.Path
End Sub
Private Sub drvLocal_Change()
dirLocal.Path = drvLocal.Drive
End Sub
Private Sub filLocal_DragDrop(Source _
As Control, X As Single, Y As
Single)
'receiving files from FTP site.
Dim I As Integer
Dim sFileList As String
If TypeOf Source Is ListBox Then
For i = 0 _
To
Source.ListCount - 1
If
Source.Selected(i) Then
sFileList = _
sFileList & _
Source.List(i) & "|"
End If
Next
End If
If Len(sFileList) > 0 Then
'strip off the last pipe
sFileList = Left(sFileList, _
Len(sFileList) - 1)
GetFiles sFileList
End If
End Sub
Private Sub _
filLocal_MouseDown(Button As _
Integer, Shift As Integer, X As _
Single, Y As Single)
filLocal.Drag vbBeginDrag
End Sub
Private Sub filLocal_MouseUp(Button _
As Integer, Shift As Integer, _
X As Single, Y As Single)
filLocal.Drag vbEndDrag
End Sub
lstRemoteFiles_DragDrop(Source _
As Control, X As Single, Y As Single)
Dim I As Integer
Dim sFileList As String
If TypeOf Source Is FileListBox Then
For i = 0 To Source.ListCount - 1
If
Source.Selected(i) Then
sFileList = sFileList & _
Source.List(i) & "|"
End If
Next
End If
If Len(sFileList) > 0 Then
'strip off the last pipe
sFileList = Left(sFileList, _
Len(sFileList) - 1)
PutFiles sFileList
End If
End Sub
Private Sub _
lstRemoteFiles_KeyDown(KeyCode _
As Integer, Shift As Integer)
If KeyCode = vbKeyDelete Then
Inet1.Execute Inet1.URL,
"DEL " & _
lstRemoteFiles.List( _
lstRemoteFiles.ListIndex)
Do
DoEvents
Loop While Inet1.StillExecuting
End If
iLastFTP = ftpDIR
Inet1.Execute Inet1.URL, "DIR"
End Sub
Private Sub _
lstRemoteFiles_MouseDown(Button _
As Integer, Shift As Integer, )
X As Single, Y As Single)
lstRemoteFiles.Drag vbBeginDrag
End Sub
Private Sub lstRemoteFiles_MouseUp(Button As _
Integer, Shift As Integer, _
X As Single, Y As Single)
lstRemoteFiles.Drag vbEndDrag
End Sub
applications more Internet-aware. Actually, the Internet offers several
solutions to some potential problems--the challenge is to take advantage of
the existing capabilities to meet those challenges. If you need to transfer
files between two Internet sites, the Internet Transfer Control offers a
quick solution. In this article, we've shown you how to use the control in
your applications. We've also pointed out a couple of bugs to work around.
Comments on this post
No comments have been added for this post.
You must be logged in to make a comment.