Click here to Skip to main content
15,860,859 members
Articles / Programming Languages / C#
Article

FTP Windows Forms Client, using Managed Assembly

Rate me:
Please Sign up or sign in to vote.
3.00/5 (12 votes)
22 Apr 20043 min read 168.8K   2.9K   32   27
This is a FTP downloading Winform application utilizing Indy.Sockets.dll.

Sample Image

Introduction

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.

Background

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.

Using the code

Demo Installation/Operation

Please extract this zip file into any directory, let us assume, it is “D:\”.

  1. Copy Indy.Sockets.dll downloaded from here into D:\Indy\bin\Debug.
  2. Open Visual Studio .NET. File/Open/Project, browse to D:\Indy; double click Indy.sln.
  3. Press F5 to start.
  4. Enter FTP Server name, user ID, and password.
  5. Click "Login", it would go to the server, and display a list of directories in the list box.
  6. Double clicking on any directory would take you to that directory, refreshing the listing.
  7. Clicking on the "^" button would take you [back to] the parent directory, refreshing the list.
  8. Double clicking on any file would prepare that file for download into current working directory.
  9. Clicking the "DOWNLOAD" button would start the transfer. It would be invisible once download starts. The status bar would show the current file being downloaded.
  10. Entering another FTP site name and clicking "Login" would log you off from current site, logging in to the new site.
  11. Closing the form would log you off the FTP server before exiting.

(If you don't have Visual Studio .NET 2003, follow README.txt for .NET Framework 1.1 nmake build)

Code Description

Setting up references/Namespaces

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.

C#
using Indy.Sockets.IndyFTP;
using System.Collections.Specialized;
using System.Text.RegularExpressions;

Load

Creates FTP instance into lFtp.

C#
private void Form1_Load(object sender, System.EventArgs e) {
    lFtp = new FTP();
}

Login

Disconnects if already logged in, uses Connect() method to login in Passive mode, drawing directory contents into ListBox.

C#
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 download

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.

C#
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 Directory

The ChangeDirUp() would do that.

C#
    private void btnCdParent_Click(object sender, System.EventArgs e) {
    statusBar1.Text="Changing to Parent Directory ..";
    lFtp.ChangeDirUp();
    drawDirectoryContents();
}

Downloading Files

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.

C#
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 Display

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.

C#
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 Closing

Before form is closed, the Disconnect() method is used to make sure FTP server gets the "BYE" command before form unloads.

C#
private void Form1_Closed(object sender, System.EventArgs e) {
    lFtp.Disconnect();
}

Summary

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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Architect Task Performance Group
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Generalgood job Pin
Lomis21-Jun-10 2:13
Lomis21-Jun-10 2:13 
Rantplease help me I didn't download Indy.Socket.dll Pin
Member 424411921-Dec-08 1:52
Member 424411921-Dec-08 1:52 
GeneralRe: please help me I didn't download Indy.Socket.dll [modified] Pin
Fakher Halim21-Dec-08 7:08
Fakher Halim21-Dec-08 7:08 
QuestionDownload Indy.Sockets.dll URL shows 404 error Pin
anbarasans3-Dec-08 18:32
anbarasans3-Dec-08 18:32 
AnswerRe: Download Indy.Sockets.dll URL shows 404 error [modified] Pin
Fakher Halim21-Dec-08 7:03
Fakher Halim21-Dec-08 7:03 
GeneralA comfortable FTP class in .NET Pin
Elmue27-Aug-08 12:40
Elmue27-Aug-08 12:40 
GeneralRe: A comfortable FTP class in .NET Pin
Fakher Halim27-Aug-08 12:42
Fakher Halim27-Aug-08 12:42 
GeneralRe: A comfortable FTP class in .NET Pin
Elmue2-Sep-08 7:41
Elmue2-Sep-08 7:41 
GeneralRe: A comfortable FTP class in .NET Pin
Fakher Halim2-Sep-08 7:53
Fakher Halim2-Sep-08 7:53 
Generalupload file into remote server in c#winform Pin
nanio31-Jan-08 20:35
nanio31-Jan-08 20:35 
Generalits very very urgent Pin
santu_kumar20-Sep-07 1:27
santu_kumar20-Sep-07 1:27 
GeneralWho wants the working fix Pin
DR Delphi2-Mar-07 3:29
DR Delphi2-Mar-07 3:29 
GeneralRe: Who wants the working fix Pin
nanio31-Jan-08 21:00
nanio31-Jan-08 21:00 
http://www.codeproject.com/KB/macros/ftp_class_library.aspx?msg=2411391#xx2411391xx.

i am using the above code and dll,

but it is not working..

erroris coming like this :An existing connection was forcibly closed by remote host.

my server has firewall settings.
i know the valid credentials.
is first enter to firewall and then server.
i dont know how to connect.

Plz send me the code my mailid :addala.venkat16@gmail.com
GeneralI don't find Indy.Sockets.dll with FTP Pin
_anagram_2-Jun-06 2:33
_anagram_2-Jun-06 2:33 
GeneralRe: I don't find Indy.Sockets.dll with FTP Pin
anagram2-Jun-06 23:55
anagram2-Jun-06 23:55 
GeneralRe: I don't find Indy.Sockets.dll with FTP Pin
DR Delphi2-Mar-07 3:31
DR Delphi2-Mar-07 3:31 
GeneralI have problem with FTP client in C#: Pin
beyzaa17-Apr-06 4:51
beyzaa17-Apr-06 4:51 
GeneralC#. Error &quot;not connected&quot; in FTP client Pin
bigman_pl17-Oct-05 7:07
bigman_pl17-Oct-05 7:07 
GeneralRe: C#. Error &quot;not connected&quot; in FTP client Pin
J. Peter Mugaas21-Oct-05 5:55
J. Peter Mugaas21-Oct-05 5:55 
GeneralRe: C#. Error &quot;not connected&quot; in FTP client Pin
bigman_pl23-Oct-05 21:30
bigman_pl23-Oct-05 21:30 
GeneralHi Pin
santosh poojari15-Sep-05 21:24
santosh poojari15-Sep-05 21:24 
GeneralAnother free, open-source .NET FTP component Pin
h_c_a_andersen11-Nov-04 11:57
h_c_a_andersen11-Nov-04 11:57 
GeneralIndy website not cooperating Pin
Paolo del Mundo28-Sep-04 8:10
Paolo del Mundo28-Sep-04 8:10 
GeneralRe: Indy website not cooperating Pin
Fakher Halim28-Sep-04 10:22
Fakher Halim28-Sep-04 10:22 
GeneralIndy 10 .NET has been released Pin
Fakher Halim4-May-04 17:25
Fakher Halim4-May-04 17:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.