|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThis 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 BackgroundThe 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. Using the codeDemo Installation/OperationPlease 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) Code DescriptionSetting up references/NamespacesThe project has been setup to refer Indy assembly D:\Indy\bin\Debug\Indy.Sockets.dll, and use using Indy.Sockets.IndyFTP;
using System.Collections.Specialized;
using System.Text.RegularExpressions;
LoadCreates FTP instance into private void Form1_Load(object sender, System.EventArgs e) {
lFtp = new FTP();
}
LoginDisconnects if already logged in, uses 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();
}
Directory Item Double Clicking: Changing Directory/Preparing for downloadWhen someone double-clicks on directory 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;
}
}
}
Changing to Parent DirectoryThe private void btnCdParent_Click(object sender, System.EventArgs e) {
statusBar1.Text="Changing to Parent Directory ..";
lFtp.ChangeDirUp();
drawDirectoryContents();
}
Downloading FilesOnce file is prepared to download by double clicking it from the list box, as explained above; the "DOWNLOAD" button would invoke the 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);
}
Directory Content DisplayThe list box is cleared first of previous contents. 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";
}
Form ClosingBefore form is closed, the private void Form1_Closed(object sender, System.EventArgs e) {
lFtp.Disconnect();
}
SummaryThe 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.
|
||||||||||||||||||||||