FTP Task in WF and TFS
January 4, 2011 2 Comments
Now that I have custom MSBuild tasks working using WF (and kicking them off using TFS), I realized that I DON”T want to use custom MSBuild tasks. It seems easier just to put in a custom WF task as part of the bdefult build template that comes out of the box in TFS. To that end, I created a new template and identified the step where I would put in this new workflow task (it took 5 minutes to click through this TFS WF, it is a beast!):
I then created a new project to get the FTP tasks working. Before using WF, I thought of just creating a Console app that does what I want. I monkeyed around with the the native .NET FTP library but is stinks and then I tried FTPLibrary – which didn’t work out of the box. I then tried EditFTP and it worked great so I used that. I created a structured program that uses the Edit FTP API to copy the contents from the build directory to the FTP site (oooh, recursion):
static FTPConnection ftpConnection = null; static string hostName = @"ftp.xxx.com"; static string userName = "xxx"; static string password = "xxx"; static string sourceLocation = @"xxx"; static string targetLocation = "xxx"; static void Main() { Console.WriteLine("Start"); ConfigureFTPConnnection(); CopyDirectoryContents(sourceLocation, targetLocation); Console.WriteLine("End"); Console.ReadKey(); } static void ConfigureFTPConnnection() { ftpConnection = new FTPConnection(); ftpConnection.UserName = userName; ftpConnection.Password = password; ftpConnection.ServerAddress = hostName; ftpConnection.Connect(); } static void CopyDirectoryContents(string sourceDirectoryName, string targetDirectoryName) { DirectoryInfo directoryInfo = new DirectoryInfo(sourceDirectoryName); ftpConnection.ChangeWorkingDirectory(targetDirectoryName); foreach (FileInfo fileInfo in directoryInfo.GetFiles()) { ftpConnection.UploadFile(fileInfo.FullName, fileInfo.Name); } foreach (DirectoryInfo subDirectoryInfo in directoryInfo.GetDirectories()) { ftpConnection.CreateDirectory(subDirectoryInfo.Name); CopyDirectoryContents(subDirectoryInfo.FullName, subDirectoryInfo.Name); } ftpConnection.ChangeWorkingDirectoryUp(); }
Pretty simple stuff – note the use of ChangingWorkingDirectoryUp to keep the current directory on the remote site synched.
I then thought about how to create a WF class that does the same thing. To do that, I fired up a VS2010 Activity diagram. My 1st cut was WAAY too complicated:
I refined it based on the fact that my FTP API automagically overwrites files:
Much easier. I then created a workflow activity (with its .asmx extension). I realized that I would simply throw a code activity on to the designer, move the procedureal code I already wrote into that activity, and call it a a day. However, I wanted to see if I can exploit the power of WF and replicate the activity diagram using workflow tasks. I’ll document my experiences with that attempt next week.
Is there a sample project I can download to get a better look at the code.
Sure, I’ll send it to your email.