Click here to Skip to main content
15,897,315 members
Articles / Programming Languages / C++

Fast Solution Build Add-in for Visual Studio .NET

Rate me:
Please Sign up or sign in to vote.
4.50/5 (23 votes)
16 Dec 20027 min read 86.6K   1.2K   27  
Performs VC6-style dependency checking for VS .NET multi-project solution builds
<html>

<head>
<meta http-equiv="Content-Language" content="en-us">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Fast Solution Build Add-in for Visual Studio .NET</title>
</head>

<body>

<h1 align="center">Fast Solution Build Add-in for Visual Studio .NET</h1>
<p>New versions of <i>Fast Solution Build</i> may be found on
<a href="http://workspacewhiz.com/">http://workspacewhiz.com/</a> in the Other 
Add-ins section.</p>
<h2>Introduction</h2>
<p>When making the transition from Visual C++ 6 to Visual Studio .NET, it became evident multi-project solution builds were quite 
  a bit slower than their Visual C++ 6 counterpart workspaces. For people working 
  in a single project environment, the difference is negligible. For multi-project 
  solutions, the pain of using the Build Solution command quickly becomes 
obvious, while waiting for all the &quot;dependency checking&quot; for every project of the solution.</p>
<p><i>Fast Solution Build</i> emulates the Visual C++ 6 build style.&nbsp; It builds on 
the concepts from the original Fast Project Build VBScript macro, while 
providing  more ease of use and error checking.&nbsp; In 
addition, the Run (Debug) command is now available.</p>
<h2>Features</h2>
<ul>
  <li>Quickly identifies and builds just those projects that have changed files.&nbsp; 
  Unlike the <code>Build Solution</code> command, no slow per project full solution dependency checks are 
  performed.</li>
  <li>If an error occurs during the build of a project, the build shuts down 
  immediately.&nbsp; The rest of the solution projects do not continue building.</li>
  <li>The equivalent of <code>Debug.Start</code> is available through the Run Active Project 
  command.&nbsp; Unlike <code>Debug.Start</code>, a slow full solution dependency check is 
  not performed.</li>
  <li>If a debug session is active, the user is 
  prompted to shut down the debug session  before the build starts.</li>
  <li>Also shows an example of &quot;proper&quot; add-in installation/uninstallation.</li>
</ul>
<h2>Installation without the Installer</h2>
<ol>
  <li>Unzip the archive.</li>
  <li>Close down Visual Studio .NET.</li>
  <li>Run <code>regsvr32 FastSolutionBuild.dll</code>.</li>
</ol>
<p>The installer offers much more ease of use, including an uninstall feature, and should be used where possible.</p>
<h3>Setting Up Keyboard Bindings</h3>
<ol>
  <li>Reopen Visual Studio .NET.</li>
  <li>Choose to either accept or not accept the default <i>Fast Solution Build</i> 
  keyboard bindings.</li>
  <li>If desired, you may install a key binding for the macro:<ol>
      <li>Go to <code>Tools-&gt;Options-&gt;Keyboard</code>.</li>
      <li>If the keyboard mapping scheme has never had a custom copy made, press 
        the <code>Save As</code> button and name your key bindings.</li>
      <li>In <code>Show commands containing:</code>, type <code>FastSolutionBuild</code>.</li>
      <li>Click on <code>FastProjectBuild.Connect.BuildActiveProject</code>.</li>
      <li>Go to <code>Press shortcut key(s)</code>.</li>
      <li>Press <code>F7</code> (or your desired key).</li>
      <li>Click <code>Assign</code>.</li>
      <li>Click on <code>FastProjectBuild.Connect.RunActiveProject</code>.</li>
      <li>Go to <code>Press shortcut key(s)</code>.</li>
      <li>Press <code>F5</code> (or your desired key).</li>
      <li>Click <code>Assign</code>.</li>
      <li>Click <code>OK</code>.</li>
  </ol>
  </li>
</ol>
<h2>Usage</h2>
<p>The <strong>bold</strong> project in the Solution Explorer is the top-level 
  project built by the <i>Fast Solution Build</i> macro.&nbsp; To make a different project 
  the &quot;startup&quot; project, right click on the desired project and choose 
  <code>Set as StartUp Project</code>.</p>
<p>Run <i>Fast Solution Build</i>'s <code>BuildActiveProject</code> or <code>
RunActiveProject</code> commands from the Tools menu or press the keyboard key 
assigned to the add-in commands.</p>
<h2>Technical Details</h2>
<p><i>Fast Solution Build</i> is a C++/ATL enhanced version of the VBScript Fast 
Project Build macro.&nbsp; It demonstrates many add-in concepts learned while 
developing the <i> <a href="http://workspacewhiz.com/">Workspace Whiz add-in for 
Visual Studio .NET</a></i>.&nbsp; Most importantly, it illustrates the steps I have 
discovered to solidly run an add-in.</p>
<p>First, <i>Fast Solution Build</i> is fully capable of installing and uninstalling 
itself through just a <code>regsvr32</code> call.&nbsp; It is far more 
convenient, especially when debugging, not to run an installer for add-in 
installations and uninstallations.&nbsp; In <code>AddIn.cpp</code>, <code>
DllRegisterServer()</code> handles registering the server and hooking up the 
add-in's registry entries.&nbsp; The critical registry keys are at <code>
HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0\AddIns\FastSolutionBuild.Connect</code> 
and&nbsp; <code>HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0\PreloadAddinState</code>.&nbsp;&nbsp; 
The <code>PreloadAddinState</code> key tells Visual Studio .NET to force 
creation of the add-in commands.&nbsp; Usually, VS .NET caches the add-in 
commands and toolbar entries.&nbsp; Unfortunately, it doesn't do a very good job 
of it and often loses the settings for them.</p>
<p><code>DllUnregisterServer()</code> illustrates a couple important functions.&nbsp; 
First, the add-in registry keys are removed, including GUIDs, typelibs, etc.&nbsp; 
Finally, <i>Fast Solution Build</i> actually connects with the VS .NET COM object and 
removes its registered commands.&nbsp; If the add-in created a toolbar (<i>Fast 
Solution Build</i> just adds commands to the Tools menu), this is an appropriate 
place to remove the toolbar, too.</p>
<p>The <code>CConnect::OnConnection()</code> code is quite a bit different from 
the boilerplate AppWizard generated code.&nbsp; It performs the following steps:</p>
<ol>
  <li><code>m_pDTE</code> and <code>m_pAddInInstance</code> are set to <code>
  NULL</code>.&nbsp; While developing <i>Workspace Whiz</i>, VS .NET called the <code>
  OnConnection()</code> function more than once without calling <code>
  OnDisconnection()</code>.&nbsp; Setting these values to <code>NULL</code> 
  ensures double <code>OnConnection()</code> calls don't crash.</li>
  <li>A test is made to see if this was launched from the command-line.&nbsp; 
  This doesn't work for all command-line cases, but it covers some of them.</li>
  <li>During the execution of the function, large blocks of code are wrapped in 
  try-catch blocks.&nbsp; When launching from a command-line build, requesting 
  the <code>CommandBars</code> object, for instance, results in Visual Studio 
  throwing an exception, instead of returning a proper error code.&nbsp; A 
  similar thing happens when trying to add a named command to the <code>Commands</code> 
  object.&nbsp; Even though you can successfully retrieve the <code>Commands</code> 
  object, called <code>AddNamedCommand()</code> also causes Visual Studio to 
  throw an exception.</li>
  <li>The Tools menu is scanned for the presence of <i>Fast Solution Build</i> 
  commands.&nbsp; If they aren't there, it recreates them.&nbsp; Some VS .NET 
  crashes don't save out command icon information and don't bother calling <code>
  OnConnection()</code> again with a <code>ConnectMode</code> of <code>5</code> 
  (which causes recreation of the toolbar items and add-in commands).&nbsp; This 
  check force recreates the commands, making the assumption they aren't there.</li>
  <li>Again, in <i>Workspace Whiz</i>, cases were seen where events weren't properly 
  unregistered, due to <code>OnDisconnection()</code> not being called.&nbsp; 
  Whole VS .NET crashes would result.&nbsp; <i>Fast Solution Build</i> unregisters the 
  event handlers before it registers them.</li>
</ol>
<p><i>Fast Solution Build</i> implements two commands, <code>BuildActiveProject</code> 
and <code>RunActiveProject</code>.&nbsp; <code>CConnect::Exec()</code> 
identifies the proper command and routes accordingly.</p>
<p><code>BuildActiveProject</code> works by performing the following steps:</p>
<ol>
  <li>If the application is currently being debugged, a dialog box pops up 
  asking the user if they want to stop debugging.&nbsp; If the answer is no,
  <code>BuildActiveProject</code> exits.</li>
  <li>Like VC6, all files are saved before the build.</li>
  <li>The Build output window pane is obtained through the function <code>
  GetOutputWindowPane()</code>.&nbsp; It is cleared and some text is displayed.</li>
  <li>If any of the solution, solution build, build dependency, or other <code>
  EnvDTE</code> objects can't be retrieved, <code>BuildActiveProject</code> 
  exits with an error.</li>
  <li>The startup projects are obtained.&nbsp; The startup projects are attached 
  to a <code>CComSafeArray</code>.&nbsp; If you attach a <code>SAFEARRAY</code> 
  to a CComSafeArray and don't intend it to be destroyed, be sure to detach it 
  or <code>CComSafeArray</code> will destroy it!</li>
  <li>All the dependencies begin to recurse.</li>
  <li>Any project that is not a C/C++ project is ignored.</li>
  <li>The solution context's &quot;should build project&quot; setting is used to ignore 
  any projects the developer turned off for the solution configuration.</li>
  <li>All required dependencies are traversed.&nbsp; If they haven't been 
  dependency checked yet, it goes back to step 6.</li>
  <li>The proper configuration and platform is retrieved for the project's 
  context.</li>
  <li>If any of the children dependencies built, then a build is automatically 
  forced for the parent projects.</li>
  <li>Finally, the <code>VCConfiguration.UpToDate</code> property is obtained.&nbsp; 
  This is truly where all the magic happens.&nbsp; It seems as if the <code>Build Solution</code> command 
  ignores the <code>UpToDate</code> property and calls <code>Build</code> all 
  the time.&nbsp; In fact, without the check for <code>UpToDate</code> in <i>Fast 
  Solution Build</i>, the macro behaves no different than <code>Build Solution</code>!</li>
</ol>
<p><code>RunActiveProject</code> expands on <code>BuildActiveProject</code> by 
doing the following extra items:</p>
<ol>
  <li>If the debugger is active, no solution build will be performed.&nbsp; 
  However, the command <code>Debug.Start</code> is fired, to simulate the <code>
  Debug</code> menu's <code>Continue</code> behavior when stepping or at a 
  breakpoint.</li>
  <li>The active project and all its updated dependencies are built.</li>
</ol>
<p>Finally, <i>Fast Solution Build</i> wedges itself into a couple BuildEvents.&nbsp; 
When <code>OnBuildProjConfigDone</code> is triggered, <i>Fast Solution Build</i> checks 
for any errors during the current project's build.&nbsp; If it finds any, it 
aborts the rest of the build through the <code>Build.Cancel</code> command.&nbsp; 
When <code>OnBuildDone</code> is triggered and no build errors occurred, <code>
Debug.Start</code> is called, causing the debugger to become active.</p>
<h2>Known Bugs</h2>
<ul>
  <li>None at this time.</li>
</ul>
<h2>Conclusion</h2>
<p>Please report any 
comments, bugs, or fixes to <a href="mailto:'jjensen@workspacewhiz.com">
jjensen@workspacewhiz.com</a>.</p>
<p>Thanks,</p>
<p>Joshua Jensen<br>
Author, <i>Fast Solution Build</i><br>
<a href="http://workspacewhiz.com/">http://workspacewhiz.com/</a></p>

<h2>Edit History</h2>
<p>4 Dec 2002 - Initial Edit</p>
<p>5 Dec 2002 - Version 2.01</p>
<ul>
  <li>Made command-line builds not crash under certain circumstances.</li>
  <li>Stopped a secondary build from overriding a build already in progress.</li>
</ul>
<p>&nbsp;</p>

</body>

</html>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
Joshua Jensen is a gamer at heart and as such, creates games for a living. He has the distinct pleasure of creating titles exclusively for the Xbox.

In his spare time, he maintains a Visual C++ add-in called Workspace Whiz! Find it at http://workspacewhiz.com/.

Comments and Discussions