libraries

Create a Team Foundation Server event handler

Sometimes you need to do special stuff when a work item, build, etc changes in your Team Foundation Server. The best option that you have is to create a server event handler. To do that you need to follow this steps:

1.- Create a new Class Library project

Create Class Library
Create Class Library

2.- Add reference to those libraries

libraries
libraries

You could add the first three ones from Assemblies -> Extensions in the add reference window:

add reference
add reference

You have to add the other two libraries from C:\Program Files\Microsoft Team Foundation Server 11.0\Application Tier\Web Services\bin

3.- Create a class that implements the ISubscriber interface

public class WorkItemChangedEventHandler : ISubscriber

4.- Implement the interface. To do that you have to implement the SubscribedTypes method:

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

The name property

public string Name
{
    get { return "WorkItemChangedEventHandler"; }
}

The priority property

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

And the ProcessEvent method

public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType,
                                                    object notificationEventArgs, out int statusCode, out string statusMessage,
                                                    out ExceptionPropertyCollection properties)
{
    statusCode = 0;
    properties = null;
    statusMessage = String.Empty;
    try
    {
        if (notificationType == NotificationType.Notification && notificationEventArgs is WorkItemChangedEvent)
        {
            var ev = notificationEventArgs as WorkItemChangedEvent;
            // Do what you want
        }
    }
    catch (Exception exception)
    {
        TeamFoundationApplicationCore.LogException("Error processing event", exception);
    }
    return EventNotificationStatus.ActionPermitted;
}

In this example we are only subscribing to WorkItemChangedEvent. But you can subscribe to another events. To do that, just add more event types in SubscribedTypes method. You could find a list of available events here.

Can I debug the library?

Yes you can, and it’s easy. First of all, change the output path in the project settings window and put C:\Program Files\Microsoft Team Foundation Server 11.0\Application Tier\Web Services\bin\Plugins\.

project properties
project properties

And after that, attach your Visual Studio 2012 to the w3wp.exe process.

Conclusion

In this article we have seen how to develop a Team Foundation Server event handler and how to debug it. A very usefull technique in some scenarios.

See you soon!

  • Konstantin

    And how to use this class? I am talking about use ProcessEvent().
    How to fill this parameters?

    • vgaltesc

      Hi Konstantin,

      the class is called by TFS, you don’t have to call it. Follow the instructions to install the event handler and it will be called by TFS.

  • Jonlondon

    Hi,

    I guess to remove the event handler simply delete the DLL in the “Plugins” directory. In my case, I wanted to rename the namespaces of my DLL. So I removed the old one and added a new. The new one works fine but the old one is still working. Is there a way to “clear” it? Or check what plugins are installed on the server side?

    Thanks

    • vgaltesc

      Have you tried to restart TFS?

  • sudhir

    Hi i have developed a tfs plugin in 2010. and then migrate it to 2012 where it was working fine. but after migrating from 2012 to tfs 2013, it is no longer working. looking at the logs in event viewer i found following exception:

    TF30059: Fatal error while initializing web service.
    TF53010: The following error has occurred in a Team Foundation component or extension:
    Date (UTC): 7/14/2014 1:43:44 PM
    Machine: RND-TFS2013
    Application Domain: /LM/W3SVC/2/ROOT/tfs-14-130498190190213468
    Assembly: Microsoft.TeamFoundation.Framework.Server, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; v4.0.30319
    Service Host:
    Process Details:
    Process Name: w3wp
    Process Id: 4840
    Thread Id: 4728
    Account name: NT AUTHORITY\NETWORK SERVICE

    Detailed Message: TF30059: Fatal error while initializing web service

    Web Request Details
    Url: http://mytfserver:8080/tfs/DefaultCollection/Services/v1.0/TeamConfigurationService.asmx [method: POST]
    User Agent: Team Foundation (devenv.exe, 12.0.21005.1, TE, SKU:14)
    Headers: Connection=Keep-Alive&Content-Length=359&Content-Type=application%2fsoap%2bxml%3b+charset%3dutf-8&Accept-Encoding=gzip&Accept-Language=en-US&Expect=100-continue&Host=rnd-tfs2013%3a8080&User-Agent=Team+Foundation+(devenv.exe%2c+12.0.21005.1%2c+TE%2c+SKU%3a14)&X-TFS-Version=1.0.0.0&X-TFS-Session=e485c555-8eee-4e0b-a8d0-9854ecb3625b%2c+GetTeamConfigurationsForUser&X-VSS-Agent=TFS%3a+b1a8d5f0-6650-4f08-931c-004721f26a5f&SOAPAction=%22http%3a%2f%2fschemas.microsoft.com%2fTeamFoundation%2f2005%2f06%2fServices%2fTeamConfiguration%2f01%2fGetTeamConfigurationsForUser%22
    Path: /tfs/DefaultCollection/Services/v1.0/TeamConfigurationService.asmx
    Local Request: True
    Host Address: fe80::418d:cf6a:7d6d:656f%12
    User: not available [authentication type: not available]

    Exception Message: A route named 'Location:ConnectionData' is already in the route collection. Route names must be unique.
    Parameter name: name (type ArgumentException)
    Exception Stack Trace: at Microsoft.TeamFoundation.Framework.Server.TeamFoundationApplicationCore.ApplicationStart()
    at Microsoft.TeamFoundation.Framework.Server.TeamFoundationModule.Module_BeginRequest(Object sender, EventArgs e)