FTP and WF: Setting the Stage
January 11, 2011 Leave a comment
Following up on my post here regarding TFS and WF, I went to write the actual WF tasks that correspond to the FTP activities of moving files over to a remote host. I crated 3 tasks
The first connects to the FTP Host:
public sealed class ConnectToHost : CodeActivity { FTPConnection _ftpConnnection = null; public InArgument<string> HostName { get; set; } public InArgument<string> UserName { get; set; } public InArgument<string> Password { get; set; } public InOutArgument<FTPConnection> FTPConnection { get; set; } public ConnectToHost() { _ftpConnnection = new FTPConnection(); } public FTPConnection ActiveConnection { get { return _ftpConnnection; } } protected override void Execute(CodeActivityContext context) { _ftpConnnection.ServerAddress = HostName.Get(context); _ftpConnnection.UserName = UserName.Get(context); _ftpConnnection.Password = Password.Get(context); _ftpConnnection.Connect(); } }
I then created a Disconnect Task:
public sealed class DisconnectFromHost : CodeActivity { FTPConnection ftpConnection = null; public DisconnectFromHost() { } public DisconnectFromHost(FTPConnection ftpConnection) { this.ftpConnection = ftpConnection; } protected override void Execute(CodeActivityContext context) { ftpConnection.Close(); } }
And finally created the Task that does the actual copying:
public sealed class CopyDirectoryContents : CodeActivity { FTPConnection ftpConnection = null; public CopyDirectoryContents() { } public CopyDirectoryContents (FTPConnection ftpConnection) { this.ftpConnection = ftpConnection; } public InArgument<string> SourceDirectoryName { get; set; } public InArgument<string> TargetDirectoryName { get; set; } protected override void Execute(CodeActivityContext context) { MoveDirectoryContents(SourceDirectoryName.Get(context), TargetDirectoryName.Get(context)); } public void MoveDirectoryContents(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); MoveDirectoryContents(subDirectoryInfo.FullName, subDirectoryInfo.Name); } ftpConnection.ChangeWorkingDirectoryUp(); } }
I then wired them up in a sequence activity and added a variable to hold the FTPConnection that will be created by the 1st task and then passed to the second and third task:
I then assigned values to the ConnectToHost parameters:
Note that FTPConnection is an InOutArgument so I can assign it from the higher level sequence.
I then added the arguments to the CopySite Task. Note that the designer handles the slashes (I couldn’t use the @”” syntax):
I got an error when I realized I don’t need to use the constructors, rather I need to use the In and OutParameters like so:
1) Create the ftpConnection and pass it out:
FTPConnection _ftpConnnection = null; public InArgument<string> HostName { get; set; } public InArgument<string> UserName { get; set; } public InArgument<string> Password { get; set; } public OutArgument<FTPConnection> FTPConnection { get; set; } protected override void Execute(CodeActivityContext context) { _ftpConnnection = new FTPConnection(); _ftpConnnection.ServerAddress = HostName.Get(context); _ftpConnnection.UserName = UserName.Get(context); _ftpConnnection.Password = Password.Get(context); _ftpConnnection.Connect(); FTPConnection.Set(context, _ftpConnnection); } }
2) Store the FTPConnection in the SequenceActivity’s local variable.
3) Get the FTP as an InArgument and use it:
public InArgument<string> SourceDirectoryName { get; set; } public InArgument<string> TargetDirectoryName { get; set; } public InArgument<FTPConnection> FTPConnection { get; set; } protected override void Execute(CodeActivityContext context) { ftpConnection = FTPConnection.Get(context); MoveDirectoryContents(SourceDirectoryName.Get(context), TargetDirectoryName.Get(context)); }
And boom goes the dynamite! It worked and the files moved over. I can now set up the FTP tasks in the TFS Build Activity.