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

FtpPublisher, An FTP File Synchronization Tool

Rate me:
Please Sign up or sign in to vote.
4.24/5 (5 votes)
12 Oct 2006CPOL3 min read 83.8K   4.2K   55   13
A small utility that will upload changed files to an FTP site
Sample Image - FtpPublisher.jpg

Introduction

I wrote this utility when I found myself having to repeatedly edit files for a Web site and then use an FTP client to upload the changes. Since I was spending my time editing images, I had to switch between multiple programs and then perform multiple steps to get the changed files uploaded. This made me want a simpler way.

FtpPublisher removes the need to manually use an FTP client or have another program that you use to publish with FTP. It will support any number of files, from various local locations to be synchronized to the remote site.

Using FtpPublisher

FtpPublisher has two modes, a design and an execution mode. As it sounds like, design mode lets you set your configuration while execution mode will take the configuration and perform the date testing and uploading.

Once your FTP connection information has been entered, FtpPublisher will retrieve the site's folder hierarchy. Each remote folder can contain a list of files that will be synchronized. This configuration can be saved into an XML file, which FtpPublisher takes as a command line argument to run in its execution mode.

To further increase the efficiency of the application, it can create a file association with its own file type. This is done by running the InstallUtil on the executable. If this is done, uploading your changes to an FTP site is as simple as double clicking the configuration file and watching it work.

The Code

FTP

All FTP functions come from edtFTPnet. I didn't use .NET 2.0's FtpWebRequest because on my initial examination, I was blind and didn't see a way for it to run in passive mode. I later looked again and realized I just hadn't scrolled down far enough, but the application was finished by then.

File Synchronization

Every file entry in the configuration contains a path and a DateTime stamp for when that file was uploaded last. It decides to upload if the file has been modified since it last wrote the stamp. I chose this method instead of getting the DateTime from the FTP because I wanted these local files to be the master copies.

C#
if (File.GetLastWriteTime(item.Path) > item.LastUpload)

Thread Synchronization with Anonymous Methods

The execution mode has its own UI. To keep that UI responsive, I have a BackgroundWorker do all the main work on a separate thread. I couldn't use its built in progress report functionality because it performs multiple types of progress updating. To simplify my life, I originally used anonymous methods inside a Control Invoke call.

C#
progressBarMain.Invoke((MethodInvoker)delegate() { });

As I was coding, I wondered if there was another way to ensure the updates were run on the correct thread. This is where SynchronizationContext comes in. It is a class designed to handle the details of which thread to perform on.

It works by getting a reference to the current thread when the Current property is accessed.

C#
SynchronizationContext context = SynchronizationContext.Current;

Then, inside the background thread, a call to its Send method will perform the work.

C#
context.Send(delegate(object state) { }, null);

Installer

Setting up file associations is an easy thing to do, but some people might not know the details of how it's done. So here is an example:

C#
public static void PerformInstall(string path)
{
    if (File.Exists(path)) 
    {
        RegistryKey key = Registry.ClassesRoot.CreateSubKey(".cFtp");
        key.SetValue("", "cFtpFileType", RegistryValueKind.String);
        key.SetValue("Content Type", "text/xml", RegistryValueKind.String);

        key = Registry.ClassesRoot.CreateSubKey("cFtpFileType");
        key.SetValue("", "Ftp Publisher Configuration", 
                     RegistryValueKind.String);
        
        RegistryKey icon = key.CreateSubKey("DefaultIcon");
        icon.SetValue("", string.Format("{0}", 
                      Path.Combine(Path.GetDirectoryName(path), "Icon.ico")), 
                      RegistryValueKind.String);

        RegistryKey cmd = key.CreateSubKey("shell\\open\\command");
        cmd.SetValue("", string.Format("\"{0}\" \"%1\"", path), 
                     RegistryValueKind.String);
    }
}

Notes

  • The configuration files store user names and passwords unencrypted.

History

  • 10-12-2006: Original article

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Canada Canada
Thomas is developer for a small service company based in the greater Vancouver area of canada. He has spent most of his time building custom c# business applications for clients.

Comments and Discussions

 
GeneralRecommend an easy to use and powerful FTP synchronizer Pin
NewTimes2024-Jun-09 4:08
NewTimes2024-Jun-09 4:08 
GeneralFile Flushing in C#( dot net) Pin
Shantonu20-Oct-08 1:03
Shantonu20-Oct-08 1:03 
QuestionRemote Folder List using FtpWebRequest? Pin
alias4714-May-07 17:41
alias4714-May-07 17:41 
AnswerRe: Remote Folder List using FtpWebRequest? Pin
Thomas Guilbault14-May-07 18:24
Thomas Guilbault14-May-07 18:24 
Each command to the ftp server uses a singe FtpWebRequest. So getting directory contents would be this. There is no built in parser for the response stream, so u get to parse it yrself. And a known thing is that one some commands ftp://contoso.com/path/ will get diffrent info than ftp://contoso.com/path

<br />
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create("ftp://contoso.com/path/");<br />
request.Credentials = new NetworkCredential(User, Password);<br />
request.Method = WebRequestMethods.Ftp.ListDirectory;<br />
WebResponse response = request.GetResponse();<br />
Stream dataStream = response.GetResponseStream();<br />

GeneralUse of the ftpclient in a commercial product... Pin
skdutta24-Apr-07 14:47
skdutta24-Apr-07 14:47 
GeneralRe: Use of the ftpclient in a commercial product... Pin
Thomas Guilbault24-Apr-07 15:51
Thomas Guilbault24-Apr-07 15:51 
QuestionPossibility to use QUOTE RCMD SBMJOB CMD()? Pin
paoloden6-Jan-07 0:58
paoloden6-Jan-07 0:58 
AnswerRe: Possibility to use QUOTE RCMD SBMJOB CMD()? Pin
Thomas Guilbault6-Jan-07 12:55
Thomas Guilbault6-Jan-07 12:55 
GeneralFTP Based Source Control Pin
HoyaSaxa9313-Oct-06 11:37
HoyaSaxa9313-Oct-06 11:37 
GeneralRe: FTP Based Source Control Pin
Thomas Guilbault14-Oct-06 14:55
Thomas Guilbault14-Oct-06 14:55 
Questionhow the hell do i add a folder !? Pin
hacx2k612-Oct-06 22:07
hacx2k612-Oct-06 22:07 
AnswerRe: how the hell do i add a folder !? Pin
Thomas Guilbault13-Oct-06 11:11
Thomas Guilbault13-Oct-06 11:11 
GeneralRe: how the hell do i add a folder !? Pin
hacx2k613-Oct-06 22:59
hacx2k613-Oct-06 22:59 

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.