TFS 2010 - Adding a menu item to the Completed Builds context menu in the Build Explorer

So, I have gotten this question a couple of times... "How can I add my own custom menu item to a TFS Build Automation context menu?" Yes, this is possible and not really that difficult. We even added some extensibility in 2010 to make this an even better experience. So, here are the steps that I followed and some tips along the way.

First you need a Visual Studio package (I think an addin will work too, but I haven’t tried that). 

  • I created a c# package by using the VS Package wizard from the New Project dialog
  • I selected to include a Menu Command and skipped most other things
  • Running the project launches a new VS and shows my menu item on the tools menu

Then, I changed the code to query for the IVsTeamFoundationBuild interface that the Build package provides.

  • First you have to add a reference for the assembly “Microsoft.VisualStudio.TeamFoundation.Build”. I directly edited the csproj file, but you should be able to do it from the add reference dialog.
  • Then I added code to the Package class in the MenuItemCallback method like this:

        private void MenuItemCallback(object sender, EventArgs e)

        {

            String message = null;

            IVsTeamFoundationBuild vsTfBuild = (IVsTeamFoundationBuild)GetService(typeof(IVsTeamFoundationBuild));

            if (vsTfBuild != null)

            {

                message = "got it!";

            }

            else

            {

                message = "Unable to get vsTfBuild.";

            }

            // Show a Message Box to prove we were here

            IVsUIShell uiShell = (IVsUIShell)GetService(typeof(SVsUIShell));

            Guid clsid = Guid.Empty;

            int result;

            Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(uiShell.ShowMessageBox(

                       0,

                       ref clsid,

                       "BuildIntegrationPackage",

                       message,

                       string.Empty,

                       0,

                       OLEMSGBUTTON.OLEMSGBUTTON_OK,

                       OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,

                       OLEMSGICON.OLEMSGICON_INFO,

                       0,        // false

                       out result));

        }

 

Next, I changed the vsct file that defines the menu to move it to the Build Explorer context menu. 

  • So, first you have to know the Guid and id of the menu where you want your menu group to show up. The two Build Explorer menus have the following guid/id pairs
    • Completed Builds
      • 34586048-8400-472e-BBBF-3AE30AF8046E
      • 0x105
    • Queued Builds
      • 34586048-8400-472e-BBBF-3AE30AF8046E
      • 0x108
  • I put my menu group on the Completed Builds menu (at the bottom)
  • Here is what that looks like in the VSCT file (this is the new Groups section):

    <Groups>

      <Group guid="guidBuildIntegrationPackageCmdSet" id="MyMenuGroup" priority="0x0600">

        <Parent guid="guidCompletedBuilds" id="menuCompletedBuilds"/>

      </Group>

    </Groups>

  • The parent guid and id names are defined in the Symbols section near the bottom:

    <!-- This is the Build Explorer Menu. -->

    <GuidSymbol name="guidCompletedBuilds" value="{34586048-8400-472e-BBBF-3AE30AF8046E}" >

      <IDSymbol name="menuCompletedBuilds" value="0x105"/>

    </GuidSymbol>

  • That should put your menu item group on the right context menu.

Then, all you have to do is write the code in your menu handler.

  • This requires you to add a reference to the assemblies Microsoft.TeamFoundation.Build.Client and Microsoft.TeamFoundation.Build.Common.
  • Here is the code to get the selected build:

            String message = null;

            IVsTeamFoundationBuild vsTfBuild = (IVsTeamFoundationBuild)GetService(typeof(IVsTeamFoundationBuild));

            if (vsTfBuild != null)

            {

                IBuildDetail[] builds = vsTfBuild.BuildExplorer.CompletedView.SelectedBuilds;

                if (builds.Length == 1)

                {

                    message = "Got Build: " + builds[0].BuildNumber;

                }

                else

                {

                    message = "Got " + builds.Length.ToString() + " Builds";

                }

            }

            else

            {

                message = "Unable to get vsTfBuild.";

            }

After doing all of that, I have a menu group at the bottom of the Completed Builds context menu that shows a message with the build number or number of builds that are selected. I didn’t cover deployment of the VS package here. You will have to look that up, but it should be pretty straight forward and well documented.

Happy coding!