Click here to Skip to main content
15,860,943 members
Articles / Programming Languages / C#

Solution Build Timer for VS 2005/2013/2015/2017/2019

Rate me:
Please Sign up or sign in to vote.
5.00/5 (24 votes)
10 Jun 2019CPOL4 min read 92.9K   1.8K   37   24
Add-in for VS2005, VS2013/2015 and VS2017/2019 that provides the time taken to build a complete solution
This add-in allows users of Visual Studio 2005, Visual Studio 2013/2015 and Visual Studio 2017/2019 to see the time taken to build a complete solution.

Background

I recently discovered a blog post that referred to an undocumented switch (/MP) in Visual Studio 2005 C++ solutions that would compile source files in multiple threads.

I wanted to determine the time saving I would get on our 30 project solution, so needed to time a solution build with and without the switch. Unfortunately, the VS2005 C++ project settings that allow you to switch on build timing will not time the entire solution, only the time to build each individual project. After suffering through two builds using a stopwatch to determine the total build times (for the record, 28m 26s without the switch, and 17m 42s with), I searched for a way to get the IDE to tell me the total build time.

Googling the problem led me to other blog and forum posts from people complaining of this missing feature (which was present back in the days of Visual Studio 6).

My solution was to use the IDE automation present in Visual Studio 2005 to add back a most welcome feature.

How the Code Works

The add-in was initially generated using the Visual Studio 2005 C# AddIn wizard. This created the framework on which the rest of the code could be hung.

The IDE automation model exposes two events, OnBuildBegin and OnBuildDone, which were perfect for use in the add-in as they are fired when a build is started and after it ends.

In the OnConnection event of the add-in, we get the window pane to which we intend to send output (in this case, the Build window) and add our own event handlers to the IDE:

C#
public void OnConnection(object application, ext_ConnectMode connectMode,
                         object addInInst, ref Array custom)
{
  _applicationObject = (DTE2)application;
  _addInInstance = (AddIn)addInInst;
  // We want our output in the Build window
  OutputWindow outputWindow = 
   (OutputWindow)_applicationObject.Windows.Item(Constants.vsWindowKindOutput).Object;
  outputWindowPane = outputWindow.OutputWindowPanes.Item("Build");
  // Add ourselves as a OnBuildBegin/OnBuildDone handler
  EnvDTE.Events events = _applicationObject.Events;
  buildEvents = (EnvDTE.BuildEvents)events.BuildEvents;
  buildEvents.OnBuildBegin += 
   new _dispBuildEvents_OnBuildBeginEventHandler(this.OnBuildBegin);
  buildEvents.OnBuildDone += 
   new _dispBuildEvents_OnBuildDoneEventHandler(this.OnBuildDone);
}

In the OnDisconnection event of the add-in, we clean up after ourselves:

C#
public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom)
{
  // Remove ourselves as a OnBuildBegin/OnBuildEnd handler
  if (buildEvents != null)
  {
    buildEvents.OnBuildBegin -=
     new _dispBuildEvents_OnBuildBeginEventHandler(this.OnBuildBegin);
    buildEvents.OnBuildDone -=
     new _dispBuildEvents_OnBuildDoneEventHandler(this.OnBuildDone);
  }
}

The meat of the add-in comes in the handlers that we added during the OnConnection event. Firstly, the OnBuildBegin event:

C#
public void OnBuildBegin(EnvDTE.vsBuildScope Scope, EnvDTE.vsBuildAction Action)
{
  // Check for a solution build for Build or RebuildAll
  if (EnvDTE.vsBuildScope.vsBuildScopeSolution == Scope &&
      (EnvDTE.vsBuildAction.vsBuildActionBuild == Action ||
       EnvDTE.vsBuildAction.vsBuildActionRebuildAll == Action))
  {
    // Flag our build timer
    amTiming = true;
    dtStart = DateTime.Now;
    outputWindowPane.OutputString(String.Format(
         "Starting timed solution build on {0}\n", dtStart));
  }
}

The OnBuildBegin event first checks that we are building a solution (as opposed to a project), and further limits our timing to the Build or Rebuild All commands (we want to ignore Clean commands). If the checks are successful, we then set a flag to say we are timing the build, get the current date and time, and send that to the Build window.

Secondly, the OnBuildDone event:

C#
public void OnBuildDone(EnvDTE.vsBuildScope Scope, EnvDTE.vsBuildAction Action)
{
  // Check if we are actually timing this build
  if (amTiming)
  {
    amTiming = false;
    dtEnd = DateTime.Now;
    outputWindowPane.OutputString(String.Format(
        "Ended timed solution build on {0}\n", dtEnd));
    TimeSpan tsElapsed = dtEnd - dtStart;
    outputWindowPane.OutputString(String.Format("Total build time: {0}\n", 
                                                tsElapsed));
   }
}

The OnBuildDone event first checks that we were actually timing the build. If that is correct, we then get the current date and time, send that to the Build window, calculate the elapsed time between the start and the end of the build and, finally, send that to the Build window.

Points of Interest

I found it quite difficult to determine what was available in terms of automation in the IDE. The MSDN Help on the subject appears to be sorely lacking for someone just starting out in the world of add-ins (this is only my third).

I did find a very helpful resource in the VS2005 Automation samples (downloadable from the Microsoft website) which gave me all the entry points I needed once I could browse the source code.

Visual Studio 2013

When Visual Studio 2013 was introduced, I noticed that there was now an option to enable build timings for C++ solutions (Tools > Options > Projects and Solutions > VC++ Project Settings > Build Timing).

I promptly enabled this option and discovered that the IDE developers had gone overboard with the detail they provide in the timing output. I still prefer the output from my original Solution Build Timer so wanted to enable it in VS2013.

Microsoft has introduced VSPackages in place of Add Ins so I created a new package in VS2013 and moved the original code across.

The result is downloadable as SolutionBuildTimer2013.zip. This contains the source code for the extension as well as a vsix package that you can install by simply double-clicking the file.

Visual Studio 2015

After installing 2015 and trying to rebuild my extension in VS2015, I discovered that the 2013 version can be built to support 2015 as well. The source and vsix package have been updated accordingly.

Visual Studio 2017

Visual Studio 2017 has changed the VSIX format which meant I had to rebuild my extension once again to support this version.

Visual Studio 2019

Visual Studio 2019 support has been added through a simple change to the manifest target versions for the VSIX.

VSIX Change

The 2017/2019 version of the extension has been updated to support asynchronous loading, as required by VS2019.

History

  • 5th June, 2019: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Comments and Discussions

 
QuestionMissing packages.config and app.config Pin
Member 136900266-Sep-19 10:24
Member 136900266-Sep-19 10:24 
AnswerRe: Missing packages.config and app.config Pin
Thornik10-Feb-22 4:08
Thornik10-Feb-22 4:08 
QuestionThis doesn't appear to work exclusively with VC++ projects, correct? Pin
roybrew6-Jun-19 5:53
roybrew6-Jun-19 5:53 
AnswerRe: This doesn't appear to work exclusively with VC++ projects, correct? Pin
User 404119-Jun-19 23:55
User 404119-Jun-19 23:55 
GeneralRe: This doesn't appear to work exclusively with VC++ projects, correct? Pin
roybrew10-Jun-19 3:12
roybrew10-Jun-19 3:12 
GeneralRe: This doesn't appear to work exclusively with VC++ projects, correct? Pin
roybrew10-Jun-19 3:19
roybrew10-Jun-19 3:19 
GeneralRe: This doesn't appear to work exclusively with VC++ projects, correct? Pin
User 4041110-Jun-19 22:23
User 4041110-Jun-19 22:23 
GeneralRe: This doesn't appear to work exclusively with VC++ projects, correct? Pin
roybrew11-Jun-19 3:30
roybrew11-Jun-19 3:30 
GeneralRe: This doesn't appear to work exclusively with VC++ projects, correct? Pin
roybrew11-Jun-19 3:44
roybrew11-Jun-19 3:44 
GeneralRe: This doesn't appear to work exclusively with VC++ projects, correct? Pin
roybrew11-Jun-19 5:37
roybrew11-Jun-19 5:37 
GeneralMy vote of 5 Pin
Jordan Walters23-Mar-12 1:48
Jordan Walters23-Mar-12 1:48 
QuestionWorks on VS2010 too! Pin
Jordan Walters23-Mar-12 1:48
Jordan Walters23-Mar-12 1:48 
GeneralMy vote of 5 Pin
Guyverthree17-Feb-12 0:02
Guyverthree17-Feb-12 0:02 
GeneralRe: My vote of 5 Pin
User 4041127-Feb-12 1:49
User 4041127-Feb-12 1:49 
Generalvs-build-timer Pin
matty_t4-Jul-09 21:20
matty_t4-Jul-09 21:20 
QuestionHow to install and does it work with VS 2008 Pin
bencbr22-Apr-09 9:49
bencbr22-Apr-09 9:49 
AnswerRe: How to install and does it work with VS 2008 [modified] Pin
User 4041122-Apr-09 18:46
User 4041122-Apr-09 18:46 
GeneralRe: How to install and does it work with VS 2008 Pin
bencbr23-Apr-09 4:24
bencbr23-Apr-09 4:24 
GeneralRe: How to install and does it work with VS 2008 Pin
User 4041123-Apr-09 4:39
User 4041123-Apr-09 4:39 
GeneralRe: How to install and does it work with VS 2008 Pin
Don Shrout5-May-09 11:20
Don Shrout5-May-09 11:20 
GeneralRe: How to install and does it work with VS 2008 Pin
Member 457912418-May-10 2:49
Member 457912418-May-10 2:49 
GeneralRe: How to install and does it work with VS 2008 Pin
User 4041118-May-10 3:04
User 4041118-May-10 3:04 
You could also add another section to the .addin file:

<HostApplication>
<Name>Microsoft Visual Studio</Name>
<Version>9.0</Version>
</HostApplication>

in which case it will be supported by both VS2005 and VS2008.
GeneralNice tool. Pin
ABlokha7716-Mar-09 7:30
ABlokha7716-Mar-09 7:30 
GeneralRe: Nice tool. Pin
User 4041116-Mar-09 19:10
User 4041116-Mar-09 19:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.