![]() |
General Programming »
Internet / Network »
Internet & Network
Intermediate
FTP Windows Forms Client, using Managed AssemblyBy Fakher HalimThis is a FTP downloading Winform application utilizing Indy.Sockets.dll. |
C#, Windows, .NET 1.0, .NET 1.1VS.NET2003, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||

This article describes how to create a fully functional FTP client Windows Forms application in C# using an external open source assembly. Despite its richness, the .NET framework library doesn�t currently have classes specifically written for FTP. This often makes many users write their own FTP client library in C#. Since this is not exactly something a typical application developer would likely to have expertise in, this article uses an existing .NET TCP/IP protocol library assembly to build a complete application. It leverages the agility of Windows Forms and regular expressions object Regex to parse the directory listing for directory navigation/file download.
The FTP functionality limitation in .NET, however, is no longer an issue because of its strong interoperability with managed assemblies written under any other language. In this article, we are using �Indy for Visual Studio .NET Developers�. Despite its Delphi origin, the interoperability with C# is not a big challenge. This (Indy.Sockets.dll) assembly is freely downloadable from here.
Please extract this zip file into any directory, let us assume, it is �D:\�.
(If you don't have Visual Studio .NET 2003, follow README.txt for .NET Framework 1.1 nmake build)
The project has been setup to refer Indy assembly D:\Indy\bin\Debug\Indy.Sockets.dll, and use Indy.Sockets.IndyFTP namespace. The namespace System.Collections.Specialized was used because StringCollection was required by List() method of IndyFTP instance.
using Indy.Sockets.IndyFTP;
using System.Collections.Specialized;
using System.Text.RegularExpressions;
Creates FTP instance into lFtp.
private void Form1_Load(object sender, System.EventArgs e) {
lFtp = new FTP();
}
Disconnects if already logged in, uses Connect() method to login in Passive mode, drawing directory contents into ListBox.
private void btnLogin_Click(object sender, System.EventArgs e) {
if(txtDirectory.Text!="")//aleady logged in; disconnect first
lFtp.Disconnect();
statusBar1.Text=string.Format("Logging into {0} ..", txtHost.Text);
lFtp.Host=txtHost.Text;
lFtp.Username=txtUserName.Text;
lFtp.Password=txtPassword.Text;
try{lFtp.Connect();}catch(Exception ex){
statusBar1.Text=ex.Message;return;
}
lFtp.Passive=true;
drawDirectoryContents();
}
When someone double-clicks on directory ListBox, using Regular Expression, the contents of column 1..8 are assumed to be the detail attributes, file/directory name would be in 9th column. Sometimes, even the file/directory names have embedded spaces, which would make them as separate fields. This is done by concatenating back them in string name.
The first column of a list box, if starting from 'd', makes the double clicking change directory; a '-' in that FTP column prepares file to be available for download.
private void lstDirectory_DoubleClick(object sender, System.EventArgs e) {
string sel=lstDirectory.SelectedItem.ToString();
string[] fields=Regex.Split(sel, " +");
const int startField=8;//the file/directory name starts after 8 fields
string name="";
for(int field=startField; field< fields.Length; field++){
name+=((field==startField)?"":" ")+fields[field];
//add aditional space for name split into multiple fields
}
if(sel[0]=='d'){//directory
statusBar1.Text=string.Format("Changing directoy to {0} ..", name);
lFtp.ChangeDir(name);
drawDirectoryContents();//redraw contents after changing directory
}else{
if(sel[0]=='-'){//plain file has '-' as first character
txtFileName.Text=name;//update the name of file to download
txtFileName.Visible=true;
btnDownload.Visible=true;
}
}
}
The ChangeDirUp() would do that.
private void btnCdParent_Click(object sender, System.EventArgs e) {
statusBar1.Text="Changing to Parent Directory ..";
lFtp.ChangeDirUp();
drawDirectoryContents();
}
Once file is prepared to download by double clicking it from the list box, as explained above; the "DOWNLOAD" button would invoke the Get() method. This would get the file into the current working directory. To make the demo short, I didn't give buttons to save it in a different location.
private void btnDownload_Click(object sender, System.EventArgs e) {
statusBar1.Text=string.Format("Downloading {0} into {1}..",
txtFileName.Text, Environment.CurrentDirectory);
btnDownload.Visible=txtFileName.Visible=false;
lFtp.Get(txtFileName.Text, txtFileName.Text, true, false);
statusBar1.Text=string.Format("Downloading of {0} into {1} is complete",
txtFileName.Text, Environment.CurrentDirectory);
}
The list box is cleared first of previous contents. List() function gets them in StringCollection ls, which is used to add items into list box.
private void drawDirectoryContents(){
statusBar1.Text="Listing directory contents ..";
lstDirectory.Items.Clear();
StringCollection ls=new StringCollection();
try{lFtp.List(ls, "", true);}catch(Exception ex){
statusBar1.Text=ex.Message;
return;
}
foreach(string file in ls){
lstDirectory.Items.Add(file);
}
txtDirectory.Text=lFtp.RetrieveCurrentDir();
btnCdParent.Visible=(txtDirectory.Text=="/")?false:true;
txtFileName.Visible=btnDownload.Visible=false;
statusBar1.Text="Complete";
}
Before form is closed, the Disconnect() method is used to make sure FTP server gets the "BYE" command before form unloads.
private void Form1_Closed(object sender, System.EventArgs e) {
lFtp.Disconnect();
}
The goal of this exercise was to leverage the .NET strengths; instead of trying to re-invent what is already available for free -- thoroughly tested and debugged (hopefully). The Indy library, according to their authors, supports 120 protocols! The .NET Framework integration allows seamless integration of these protocols to any managed application.
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 22 Apr 2004 Editor: Smitha Vijayan |
Copyright 2004 by Fakher Halim Everything else Copyright © CodeProject, 1999-2009 Web19 | Advertise on the Code Project |