How to create and debug a Team Foundation Server server-side plugin

Create the project

Developing a TFS server-side plugin has several advantages, including the ability to capture all the occurred events without exception.
On the other hand, the official documentation on this practice has huge gaps, so that this wiki page is intended to fill it.
First of all you need to create a standard C# class library project. This library must implement one of two interfaces to extending TFS:
  • ISubscriber – real-time, in-process event subscription.
  • ITeamFoundationRequestFilter – inspect all requests.
Now you have to add the right references: the first to the Microsoft.TeamFoundation.Framework.Server.dll assembly that can be found in <TFS-Home>\Application Tier\Web Services\bin directory, and the others to the assemblies that contain the events that you want to subscribe to.
Here's an example of a ISubscriber plugin that subscribes to WorkItemChangeEvent:

using System;
using System.Text;
using Microsoft.TeamFoundation.Common;
using Microsoft.TeamFoundation.Framework.Server;
using Microsoft.TeamFoundation.WorkItemTracking.Server;
using System.Net.Mail;

namespace ExtendingTFS
{
 class ExtendingTFS : ISubscriber
 {
  public string Name
  {
   get { return "Send email to admin"; }
  }

  public SubscriberPriority Priority
  {
   get { return SubscriberPriority.Normal; }
  }

  public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext,
                                              NotificationType notificationType,
                                              object notificationEventArgs,
                                              out int statusCode,
                                              out string statusMessage,
                                              out ExceptionPropertyCollection properties)
  {
   statusCode = 0;
   statusMessage = string.Empty;
   properties = null;
   if (notificationType == NotificationType.Notification)
   {
    try
    {
     if (notificationType == NotificationType.Notification
         && notificationEventArgs is WorkItemChangedEvent)
     {
      WorkItemChangedEvent ev = notificationEventArgs as WorkItemChangedEvent;
      StringBuilder mailbody = new StringBuilder();
      mailbody.AppendLine(string.Format("WorkItem {0} modified.", ev.WorkItemTitle));
      MailMessage mail = new MailMessage();
      mail.From = new MailAddress("notification@extendingtfs.org");
      mail.Subject = "Label applied";
      mail.To.Add(new MailAddress("admin@extendingtfs.org"));
      mail.Body = mailbody.ToString();
      SmtpClient smtp = new SmtpClient();
      smtp.Host = "localhost";
      smtp.Port = 25;
      smtp.Send(mail);
     }
    }
    catch (Exception)
    {
    }
   }
   return EventNotificationStatus.ActionApproved;
  }

  public Type[] SubscribedTypes()
  {
   return new Type[] { typeof(WorkItemChangedEvent) };
  }
 }
}

In this case, inside the ProcessEvent method, the plugin sends via email the name of a workitem when someone changes it, but you can make it do what you want.

Deploy the project

Before you build the library, you must open project properties (Project → <Project-Name> Properties...), go to Build tab and change the Output Path directory by entering <TFS-Home>\Application Tier\Web Services\bin\Plugins.

Project Properties

Now you can build the library (Build → Build Solution): Visual Studio will put it in the specified folder.
Team Foundation Server has noticed that a new version of the event handler has been dropped in the plugins folder and therefor it is performing a restart. Right now the plugin is already active, but you still can not debug.

Debug the project

Debugging is useful to verify that everything works fine and know what the parameters contain, which are both necessary since these events are not well documented.
To do this you need to attach a process (Debug → Attach to Process...), check both Show processes from all users and Show processes in all sessions and locate the w3wp.exe process that hosts Team Foundation Server.

Attach to Process

Now you must only select Attach to start the debugging session, set a break point in the ProcessEvent method and then modify a work item in Team Foundation Server.

Debugging Session

Note: to verify that the sample library works, you can install smtp4dev, a tool that emulates a SMTP server.

Last edited Feb 12, 2014 at 2:15 PM by fcalefato, version 2