TFS 2010 Upload build from droplocation to FTP Activity C#

I had a recent request from a client asking to upload the build from the droplocation to an FTP drop location. I thought that this may prove useful for others:

Activity – C# .Net 4.0:

using System;
 using System.Activities;
 using System.IO;
 using System.Text.RegularExpressions;
 using Microsoft.TeamFoundation.Build.Client;
 using Microsoft.TeamFoundation.Build.Workflow.Activities;
 using Microsoft.TeamFoundation.VersionControl.Client;
 using System.Net;
namespace BuildTasks.Activities
 {
 [BuildActivity(HostEnvironmentOption.Agent)]
 public sealed class FTPUpload : CodeActivity
 {
 [RequiredArgument]
 public InArgument FTPUrl { get; set; }
[RequiredArgument]
 public InArgument Username { get; set; }
[RequiredArgument]
 public InArgument Password { get; set; }
[RequiredArgument]
 public InArgument DropLocation { get; set; }
// Obtain the runtime value of the input arguments
 string ftpURL = null;
 string username = null;
 string password = null;
 string dropLocation = null;
 string folder;
protected override void Execute(CodeActivityContext context)
 {
 ftpURL = context.GetValue(this.FTPUrl);
 username = context.GetValue(this.Username);
 password = context.GetValue(this.Password);
 dropLocation = context.GetValue(this.DropLocation);
Stream requestStream = null;
 FileStream fileStream = null;
 FtpWebResponse uploadResponse = null;
 try
 {
 if (Directory.Exists(dropLocation))
 {
 string[] folders = dropLocation.Split(new Char[] { '\\' });
 folder = folders[folders.Length - 1];
 }
 else
 {
 throw new DirectoryNotFoundException(String.Format("Drop Location Directory: \"{0}\", does not exist.", dropLocation));
 }
if (!(ftpURL.EndsWith("/"))) { ftpURL += "/"; }
FtpWebRequest uploadRequest;
 ICredentials credentials = new NetworkCredential(username, password);
 string[] fileNameParts;
 string fileName;
uploadRequest =
 (FtpWebRequest)WebRequest.Create(ftpURL + folder);
uploadRequest.Method = WebRequestMethods.Ftp.MakeDirectory;
 uploadRequest.Credentials = credentials;
uploadRequest.Proxy = null;
 uploadRequest.UsePassive = true;
uploadResponse =
 (FtpWebResponse)uploadRequest.GetResponse();
uploadResponse.Close();
foreach (string file in Directory.GetFiles(dropLocation))
 {
 fileNameParts = file.Split(new Char[] { '\\' });
 fileName = fileNameParts[fileNameParts.Length - 1];
uploadRequest =
 (FtpWebRequest)WebRequest.Create(ftpURL + folder + @"/" + fileName);
uploadRequest.Method = WebRequestMethods.Ftp.UploadFile;

uploadRequest.Credentials = credentials;

 uploadRequest.Proxy = null;
 uploadRequest.UsePassive = true;
requestStream = uploadRequest.GetRequestStream();
 fileStream = File.Open(file, FileMode.Open);
 byte[] buffer = new byte[1024];
 int bytesRead;
 while (true)
 {
 bytesRead = fileStream.Read(buffer, 0, buffer.Length);
 if (bytesRead == 0)
 break;
 requestStream.Write(buffer, 0, bytesRead);
 }
 //The request stream must be closed before getting
 //the response.
 requestStream.Close();
 uploadResponse =
 (FtpWebResponse)uploadRequest.GetResponse();
 }
 }
 catch (UriFormatException ex)
 {
}
 finally
 {
 if (uploadResponse != null)
 uploadResponse.Close();
 if (fileStream != null)
 fileStream.Close();
 if (requestStream != null)
 requestStream.Close();
 }
 }
 }
 }
Advertisements

About jpadda

Technical Consultant currently working as part of the .Net team for EMC Consulting.
This entry was posted in Uncategorized. Bookmark the permalink.

11 Responses to TFS 2010 Upload build from droplocation to FTP Activity C#

  1. Juriaan Bleij says:

    Hi Jag,

    I’m sorry contacting you this way but I couldn’t find another way. I read a comment you placed on this site: http://www.ewaldhofman.nl/post/2010/05/17/Customize-Team-Build-2010-e28093-Part-6-Use-custom-type-for-an-argument.aspx. About a problem you got working with the values that are being ignored when queueing a new build. I have the same problem but I don’t get your solution working. You wrote that you need to return a new Credential object but where exactly do you do that?

    Thanks in advance,
    Juriaan

  2. jpadda says:

    Hi Juriaan,

    In Ewald’s example, you put the “return new Credential() { Username = selected.Username, Password = selected.Password}; ” in place of “return value” in the example code in section “Credential Editor – 13.The full code of the class is the following: …”

    If it’s not working for you, make sure you’re compiling the code in C# version 4.0

    Thanks
    J Padda

    • Juriaan Bleij says:

      Ok, thnx for the quick response. That was also my first option but what is “selected” referring to then exactly? Because I think that’s where I go wrong.

      • jpadda says:

        Hi Juriaan,

        Apologies, “selected” is incorrect. It was a quick response using my own code! So I should be more careful when copying and pasting! In Ewald’s example, it should be,

        return new Credential() { Username = credential.Username, Password = credential.Password};

  3. Juriaan Bleij says:

    Thanx. That works fine indeed. Well I had to restart VS after I made that change because it didn’t work with a VS I allready had open. But now it works. Great!!

  4. Gautam says:

    Hey are you missing something here?
    I tried to run this code but it said the code does not have “main” method to execute.
    Please let me know where am I missing, I am pretty new to TFS, In fact this is my first day on TFS where I need to put my build files to FTP from my local machine.

  5. jpadda says:

    Hi,

    Are you trying to create a console application, or something like that? This should be compiled as an assembly and used with the TFS2010 teambuild workflow as a custom activity.

    Thanks
    JPadda

  6. jpadda says:

    Hi,

    It’s not something that I can answer in a quick email. You should probably read Ewald’s excellent blog:
    http://www.ewaldhofman.nl/post/2010/04/20/Customize-Team-Build-2010-e28093-Part-1-Introduction.aspx

    Ta
    Padda

    • Gautam says:

      Hi,
      sorry to bother you again.
      I have created the activity that you mentioned here in the blog.
      Now the issue is how to put it up in the template for my build.
      I am very much confused looking here and there.
      can you please help me or give me your personal mail id so that I can add you there and we can have a small session.
      thanks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s