
Contents
The purpose of this application is to create a fully functional FTP application that accomplishes most of the tasks professional FTP programs accomplish. The are two builds of this application:
- Windows 7-specific build: There is nothing different except that this application uses the Windows 7 features.
- All Windows systems-build: This build will work on most Windows systems (e.g.: XP/Vista). There is nothing different in this build, except that this build lacks Windows 7 features.
This application uses the following libraries:
- An FTP client library for .NET 2.0.
I decided to use this FTP library because it is well written and self explanatory. The author, Howard Richards, did a great job creating the library. However, the FTP library is missing some key features which are necessary for an FTP program. Therefore, I decided to modify the library. The following features have been added to this library:
DownloadProgressChanged
event with percentage
DownloadCompleted
event
UploadProgressChanged
event with percentage
UploadCompleted
event
- Changed some code and fixed a bug or two
MessageReceived
event - with COMMAND and RESPONSE techniques like FileZilla
- Raises event when a new message is received
- Cancel download
- Cancel upload
- Welcome message
- Enhanced BrowseForFolder styled TreeView
This treeview, created by Chris Richner, displays all the directories in the file system in a treeview. In Win7 FTP, we will use this treeview for drag and drop operations. For example, dragging a file from the FTP sever and dropping it into this treeview will save the file to the path where the file was dropped.
- Windows API Code Pack for Microsoft .NET Framework
Source code library that can be used to access some features of Windows 7 and Windows Vista from managed code.
*Note: All the library DLLs have been referenced in the Win7 FTP project. In case the references are missing, you can simply click on the appropriate library above and download it. For any other questions, you can post a message.
Well, you probably read the discussion on the bottom about the Windows XP/Vista version of this application. Someone suggested not making a version specific built, rather using if(CoreHelpers.RunningOnWin7)
to run Windows specific features on a Windows 7 machine.
I was working on that; however, in this FTP application, there is a feature of Windows 7 called GlassForm, which displays the aero form. I use this feature for the Login form, Upload form, and the Download form. There is no way of running an application that displays a GlassForm. Even if you don't want the Aero feature. An error is thrown in any case. Also, in the UI, I am using a CommandLink
, which is also part of the Windows API. That would not work on Windows XP.
So I created two builds: one that focuses on Windows 7 features and FTP, and the other that just focuses on Windows 7. Not a big deal to have two builds. If you want a Windows 7 build so you can explore Windows 7 features with FTP, you can get that. Else, you can just get the normal version.
As you all know, with Windows 7 was introduced some of the coolest libraries we have ever seen in the Windows API history. Well, to most developers, it is the coolest Microsoft has created for us. Usually, we have to do a lot ourselves, but the Windows API Code Pack does most of the things for us.
So I decided to use some of those features in this application. You will find the following features:
- The Aero Window: The Login form, Download form, and the Upload form use the Aero feature, which makes the form transparent.
- TaskBar: When download/upload progress changes, you can see the change in the taskbar.
- CommonOpenFile dialog: This is an advanced Open File dialog which has many new features and can also act as a FolderBrowse dialog.
- Command Link: I just added this to make the UI look good. It does nothing more than a button, however, it does look more professional.
- TaskDialog: This is displayed after a download has completed. It displays two options: Open File and Open Folder containing the file.
I made the taskbar progress changing a little easier in the code by creating a new class called TaskBarManager
. This class makes changing the progress easier, because it already has all the code setup. The code of the class follows:
public static void SetProgressValue(int Progress, int Maximum)
{
TaskbarProgressBarState state = TaskbarProgressBarState.Normal;
TaskbarManager.Instance.SetProgressState(state);
TaskbarManager.Instance.SetProgressValue(Progress, Maximum);
}
public static void SetTaskBarProgressState(TaskbarProgressBarState state)
{
TaskbarManager.Instance.SetProgressState(state);
}
public static void ClearProgressValue()
{
TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.NoProgress);
}
And I can call the code from the application, from any form, just like this:
TaskBarManager.SetProgressValue(Progress, TotalProgress);
HelperClasses.TaskBarManager.SetTaskBarProgressState(
Microsoft.WindowsAPICodePack.Taskbar.TaskbarProgressBarState.Error);
This has nothing special like the Windows 7-specific build. This does the job of the FTP application in the same way as the Windows 7 build.
This application contains the following forms (each will be discussed in detail).
- frmLogin.cs - Saves the user details, sets up and shows
frmMain
.
- frmMain.cs - Manages all the FTP operations and displays files and directories.
- frmRename.cs - Renames a file.
- frmNewFolder.cs - Creates a new folder.
- frmDownload.cs - Downloads a file, displays download information (progress, etc.).
- frmUpload.cs - Uploads a file, displays upload information (progress, etc.).

Since our FTP client is stateless, we will only save the hostname, username, and password. This is how the frmLogin
works:
try
{
FTPclient objFtp = new FTPclient(txtHostName.Text,
txtUserName.Text, txtPassword.Text);
objFtp.CurrentDirectory = "/";
Setup our frmMain variable
frmMain Main = new frmMain();
Main.SetFtpClient(objFtp);
Main.Show();
this.Hide();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
This form is responsible for all the FTP actions that will take place in this program. The following tasks take place in frmMain
:
- Double click navigation (like Windows): If you double click a folder, the folder is opened and all files and folders in it are shown in the listview. If you double click a file, then the user is prompted on whether he/she wants to save the file.
- Back button navigation: Clicking this will take the user a folder backwards. Nothing happens if we are at the root folder.
- Directory creation: The user can create a new directory.
- Rename file: The user can rename a file.
- Delete file/Directory: The user can delete a file.
- Download file: The user can select a location to save the file.
- Upload file: The user can select a file to upload to the current directory.
- Local file system navigation: The user can navigate to different folders in the file system using the treeview, or by entering the directory path in the textbox, or by opening the OpenFolder dialog, which automatically selects the folder in the treeview.
- Messages: When a message is sent, as a COMMAND, or received as a, RESPONSE, it is displayed in the listview with additional information, like date, message, status code, etc.
Most of these functions will be explained in more detail with code, in the FTP library explanation section of this article.
Let's look into SetFtpClient
which we called in frmLogin
. We only call this once.
public void SetFtpClient(Win7FTP.Library.FTPclient client)
{
FtpClient = client;
Message = new ListViewItem();
Message.Text = DateTime.Now.ToLongTimeString() + " " +
DateTime.Now.ToLongDateString();
Message.SubItems.Add("Welcome Message");
Message.SubItems.Add(FtpClient.WelcomeMessage);
Message.SubItems.Add("No Code");
Message.SubItems.Add("/");
lstMessages.Items.Add(Message);
FtpClient.OnNewMessageReceived +=
new FTPclient.NewMessageHandler(FtpClient_OnNewMessageReceived);
foreach (FTPfileInfo folder in FtpClient.ListDirectoryDetail("/"))
{
ListViewItem item = new ListViewItem();
item.Text = folder.Filename;
if (folder.FileType == FTPfileInfo.DirectoryEntryTypes.Directory)
item.SubItems.Add("Folder"); else
item.SubItems.Add("File");
item.SubItems.Add(folder.FullName);
item.SubItems.Add(folder.Permission);
item.SubItems.Add(folder.FileDateTime.ToShortTimeString() +
folder.FileDateTime.ToShortDateString());
item.SubItems.Add(GetFileSize(folder.Size));
lstRemoteSiteFiles.Items.Add(item);
}
}
lstRemoteSitesFiles
- A ListView
that displays all the files and folders in a directory on the FTP server.
tvFileSystem
- A TreeView
control from Chris Richner. Displays all the directories in the file system and helps in drag and drop.
lstMessages
- A ListView that displays messages, like LIST
for ListDirectoryDetail
, which is a Command.
This form helps in renaming a file. We can only rename files; we cannot rename folders. Two important things about this form is the constructor and renaming the file.
string Path, Extension, FileName;
frmMain ForMain;
public frmRename(string fileName, string CurrentDir, frmMain MainForm, string extension)
{
Path = CurrentDir; Extension = extension; FileName = fileName; ForMain = MainForm;
InitializeComponent();
AeroGlassCompositionChanged +=
new AeroGlassCompositionChangedEvent(Form1_AeroGlassCompositionChanged);
if (AeroGlassCompositionEnabled)
{
ExcludeControlFromAeroGlass(pnlNonTransparent);
}
else
{
this.BackColor = Color.Teal;
}
this.Text = "Rename " + FileName;
lblFileName.Text = "Filename: " + FileName;
lblLocation.Text = "Location: " + Path;
}
This renames the file to the new file's name.
ForMain.FtpClient.CurrentDirectory = Path;
ForMain.FtpClient.FtpRename(FileName, txtRenameTo.Text);
This form is nothing but a dialog. When the new directory name is entered in the textbox and OK is clicked, DialogResult.OK
is returned to frmMain
.
The code works like this in frmMain
:
frmNewFolder NewFolderForm = new frmNewFolder();
if (NewFolderForm.ShowDialog() == DialogResult.OK)
{
FtpClient.FtpCreateDirectory(FtpClient.CurrentDirectory +
NewFolderForm.NewDirName);
RefreshDirectory();
}
RefreshDirectory()
is a function in frmMain
which I call when an operation like Upload File, Delete File, or Rename File occurs. The function basically reloads all the files and folders in the current directory into the lstRemoteSiteFiles
in frmMain
.

This form manages the download information. When we are downloading a file, we now have two events that inform us on what is happening. These events were not in the original FTP Library, I manually implemented them.
- Starting a download.
- Display progress, download percentage, and bytes downloaded.
- Show a task dialog when the download finishes. The task dialog has three options:
- Open file - Opens the file that was recently downloaded.
- Open folder containing the file - Open the folder that contains the file.
- Closes the task dialog and the form.
- Cancel the download.
The constructor starts the download when the required arguments are passed in. The variables required are:
string FileName, SaveFilePath, CurrentDirectory;
FTPclient FtpClient;
The constructor follows:
public frmDownload(string Filename, string Current_Directory,
string SavePath, FTPclient Ftpclient)
{
InitializeComponent();
FileName = Filename;
SaveFilePath = SavePath;
CurrentDirectory = Current_Directory;
lblDownloadFrom.Text = Ftpclient.Hostname +
Current_Directory + FileName;
lblSavePath.Text = SaveFilePath; FtpClient = Ftpclient;
this.Show();
FtpClient.CurrentDirectory = Current_Directory;
FtpClient.OnDownloadProgressChanged += new
FTPclient.DownloadProgressChangedHandler(
FtpClient_OnDownloadProgressChanged);
FtpClient.OnDownloadCompleted += new
FTPclient.DownloadCompletedHandler(FtpClient_OnDownloadCompleted);
FtpClient.Download(FileName, SavePath, true);
}
OnDownloadCompleted
- Fires when the download completes.
void FtpClient_OnDownloadCompleted(object sender, DownloadCompletedArgs e)
{
if (e.DownloadCompleted)
{
MessageBox.Show("Download Completed!");
}
else
{
MessageBox.SHow("Error: " + e.DownloadStatus);
}
}
OnDownloadProgressChanged
- Manages the progress of the download.
void FtpClient_OnDownloadProgressChanged(object sender, DownloadProgressChangedArgs e)
{
progressBar1.Maximum = Convert.ToInt32(e.TotleBytes);
progressBar1.Value = Convert.ToInt32(e.BytesDownloaded);
Int64 PercentProgress =
Convert.ToInt64((progressBar1.Value * 100) / e.TotleBytes);
}
To cancel a download, simply call FtpClient.CancelDownload()
. I created this to use if the user wants to cancel a download. This function does a verification before performing anything, and deletes the the download since it is not completed.
This form manages the upload file information. When we upload a file, we now have two events that inform us on what is happening. These events were not in the original FTP Library, I manually implemented them.
- Start uploading the file
- Display upload progress, upload percentage, and bytes uploaded/total bytes.
- Display message box when upload process finishes.
- Cancel an upload.
The constructor starts uploading the file when it is called. The variables required are:
string FileName;
FTPclient FtpClient;
The constructor:
public frmUpload(string UploadFilePath, string UploadDirectory, FTPclient Ftpclient)
{
InitializeComponent();
FileName = System.IO.Path.GetFileName(UploadFilePath);
FtpClient = Ftpclient;
this.Show();
FtpClient.CurrentDirectory = UploadDirectory;
FtpClient.OnUploadCompleted += new
FTPclient.UploadCompletedHandler(FtpClient_OnUploadCompleted);
FtpClient.OnUploadProgressChanged += new
FTPclient.UploadProgressChangedHandler(FtpClient_OnUploadProgressChanged);
FtpClient.Upload(UploadFilePath, UploadDirectory + FileName);
}
OnUploadProgressChanges
- Fired when the progress of the upload changes.
void FtpClient_OnUploadProgressChanged(object sender, UploadProgressChangedArgs e)
{
progressBar1.Maximum = Convert.ToInt32(e.TotleBytes);
progressBar1.Value = Convert.ToInt32(e.BytesUploaded);
Int64 PercentProgress = Convert.ToInt64((e.BytesUploaded * 100) / e.TotleBytes);
}
OnUploadComplete
- Fires when the file is uploaded.
if (e.UploadCompleted)
{
MessageBox.Show("Upload Completed!");
}
else
{
MessageBox.Show("Error: " + e.UploadStatus);
}
To cancel an upload, simply call FtpClient.CancelUpload()
. I created for using if the user wants to cancel an upload. This function does a verification before performing anything, and deletes the upload on the server since it is incomplete.
As I told you, I made many changes to this library to meet the needs of this application. Let me explain to you each important function and what it does and how to use it.
This creates a new directory.
FtpClient.FtpCreateDirectory(CurrentDirectory + NewDirectoryName);
This renames a file. *Note: This only applies to files, you cannot rename folders.
FtpClient.CurrentDirectory = "/Directory/";
FtpClient.FtpRename("OldFileName.txt", "NewFileName.txt");
This method will allow you to delete a file.
FtpClient.CurrentDirectory = "/Directory/";
FtpClient.FtpDelete(FileName);
This method will allow you to delete a directory.
FtpClient.CurrentDirectory = "/Directory/";
FtpClient.FtpDeleteDirectory(lstRemoteSiteFiles.SelectedItems[0].SubItems[2].Text);
This method will allow you to download a file from the server.
FtpClient.CurrentDirectory = "/Directory/";
FtpClient.Download(FileName, SavePath, true);
This method will upload a file to the server.
FtpClient.Upload(UploadFilePath, UploadDirectory + FileName);
This method grabs all the folders and files in a directory and displays all their information.
foreach (FTPfileInfo folder in FtpClient.ListDirectoryDetail(txtRemoteDirectory.Text))
{
folder.Filename; if (folder.FileType == FTPfileInfo.DirectoryEntryTypes.Directory)
else
folder.FullName; folder.Permission; folder.FileDateTime.ToShortTimeString() + folder.FileDateTime.ToShortDateString();
item.SubItems.Add(GetFileSize(folder.Size)); }
I achieved my goal and created a fully functional FTP program. It is not the best, I am going to update it in the future to make it better. If you know of a way to improve this application, then comments/suggestions are welcome. I created this application in a week and had a lot of issues with bugs. So I won't say it is perfect. But thanks for hanging by and giving the program a try.
Future releases of this application will have the following features, plus more!
- Download multiple files
- Upload multiple files
- Download folders and zipped files
- Keep track of all FTP sites, user names, and passwords
- Create a custom JumpList and show FTP sites there, so when the user clicks on an FTP site, a new instance of Win7 FTP will open the FTP site
For users not running Windows 7, I will post another article which will support most Windows systems.
Revision 2/9/2010
- Added a new build which supports most modern Windows PCs.