TFS 2010 – Displaying Custom Build Information in Visual Studio

In TFS 2008, we had a lot of requests to make the Build Details View customizable. In 2010, we have taken the first step in that direction. In this post, I will explain how to change the Log View of the new Build Details View to show custom build information.

For reference you may want to check out Patrick’s blog post on adding custom build information in 2010 and my previous post on the Log View of the new Build Details View.

 

The Scenario:

One of the things we don’t show anymore on the build details view is the start and finish times of the build. We show duration instead. So, to “fix” this I want to at least show the start and finish times in the Log View. These won’t be perfect, but they will be the first and last things that happen.

Changes to the DefaultTemplate.xaml file:

First, I want to write out the start time and finish time as build information. But, I really don’t want to create a new class just to hold a string and a time. So, for this post I am going to cheat and use a type that is basically just a couple of Strings – PlatformConfiguration. I am really just doing this to keep the post reasonably short. I don’t recommend that you use this object in this way. In fact, as you may be able to tell from the code samples, I tried to use a Tuple<String, DateTime> object first, but all types of Generics aren’t fully supported by the Workflow Designer.

Anyway, here’s the XAML I added to the beginning of the build process (right after the first ending tag for Sequence.Variables).

<mtbwa:WriteBuildInformation x:TypeArguments="mtbwa:PlatformConfiguration" Value="[New PlatformConfiguration(&quot;Start Time&quot;, DateTime.Now.ToString())]" />

And this is added at the end of the XAML (right before the final ending tag for Sequence).

<mtbwa:WriteBuildInformation x:TypeArguments="mtbwa:PlatformConfiguration" Value="[New PlatformConfiguration(&quot;Finish Time&quot;, DateTime.Now.ToString())]" />

Then I ran a build of a simple hello world application, but nothing shows up in the log view of the build details view. I tried again with Verbosity set to Diagnostic, still nothing. And that’s by design. Your build information is hidden by default. You have to register a converter for it and install that converter somehow with the Visual Studio client. We don’t provide a default converter for every kind of build information.

Creating my own converter to show my new type:

The next thing I had to do was create a class that can convert my new build information into a WPF paragraph. The class has to implement the interface IBuildDetailInformationNodeConverter (which can be found in the Microsoft.TeamFoundation.Build.Controls assembly). This interface has one property and one method. The property called InformationType must return the type of information node the converter works on (in my case that’s PlatformConfiguration). The method called Convert takes in the information node (and some other info) and returns an object. The object must be a WPF Paragraph (if not you will see a cast error in your log view output).

My converter class:

 using System;
using System.Windows.Documents;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Build.Controls;

namespace CustomBuildInformationConverters
{
    class NameDateTimeTupleConverter : IBuildDetailInformationNodeConverter
    {
        public object Convert(IBuildDetailView view, IBuildInformationNode node, double parentIndent)
        {
            String description = node.Fields["Platform"];
            String time = node.Fields["Configuration"];
            return new Paragraph(new Run(String.Format("{0} : {1}", description, time)));
        }

        public string InformationType
        {
            get { return "PlatformConfiguration"; }
        }
    }
}

I put this class into a Visual Studio AddIn that I created using the Wizard. For more information on creating a VS add-in, try this article. Here is the code to register/unregister my converter with the Build Details View:

 public void OnStartupComplete(ref Array custom)
{
    IVsTeamFoundationBuild VsTfBuild = (IVsTeamFoundationBuild)_applicationObject.DTE.
        GetObject("Microsoft.VisualStudio.TeamFoundation.Build.VsTeamFoundationBuild");

    if (VsTfBuild != null)
    {
        _converter = new NameDateTimeTupleConverter();
        VsTfBuild.DetailsManager.RegisterLogViewInformationConverter(_converter);
    }
}

public void OnBeginShutdown(ref Array custom)
{
    if (_converter != null)
    {
        IVsTeamFoundationBuild VsTfBuild = (IVsTeamFoundationBuild)_applicationObject.DTE.
            GetObject("Microsoft.VisualStudio.TeamFoundation.Build.VsTeamFoundationBuild");

        VsTfBuild.DetailsManager.UnregisterLogViewInformationConverter(_converter);
    }
}
        
private DTE2 _applicationObject;
private AddIn _addInInstance;
private NameDateTimeTupleConverter _converter;

 

And here is how the Log View looks now (arrow added for emphasis):

image

In conclusion, I just want to say that there are many other things you can do with a Paragraph than simply display text and you will see some of those things in upcoming posts.

Enjoy!