Visual Studio - Stopping a Multi-Project build at the first compile error
Yet another Note to Self post--
UPDATE 11/30/2014 - This functionality has been totally replaced in VS 2010 and up by one of several extensions
(like this, or this) that will do the same thing, much more effectively...
In almost all the cases where I’m working on projects, I have multiple assemblies in the solution… In a lot of cases, I’ll make changes in one of the dependencies of my solution and when I get to a later step in the build, something else breaks.
A lot of the time, once I work my way back through the pack of build errors, I’ll find that way up my dependency tree, one of my projects had a compile error and it has trickled down through the rest of the build, causing one error after another.
A long time ago, from a source unknown to me now I found a snippet of a Visual Studio Macro that got close to what I wanted and over the years, I’ve done some slight modifications and improvements to it and still use it. It’s really simple, but it something that helps my workflow in small but measureable way.
So here is what I do… [after the break]
I go into the Visual Studio Macro IDE and add a new module.
Once you have the IDE open, I Right-click on 'MyMacros’ and add a new module
I call the module CraigsVBModule [original, huh?]. Then add the following content to my module - this module has several other items that I use, but for this example, I’ve just minimize it to what’s important.
1: Imports System
2: Imports EnvDTE
3: Imports EnvDTE80
4: Imports EnvDTE90
5: Imports EnvDTE90a
6: Imports EnvDTE100
7: Imports System.Diagnostics
8:
9: Public Module CraigsVSModule
10:
11: '<SNIP>
12: 'OTHER CODE
13: '</SNIP>
14:
15: Public Sub BuildProjConfigDone( _
16: ByVal Project As String, _
17: ByVal ProjectConfig As String, _
18: ByVal Platform As String, _
19: ByVal SolutionConfig As String, _
20: ByVal Success As Boolean)
21:
22: 'Get the output window
23: Dim win As Window = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput)
24: Dim OW As OutputWindow = CType(win.Object, OutputWindow)
25:
26: 'if the build failed, then stop further builds and output error message to
27: 'output panel
28: If Success = False Then
29: 'cancel further builds
30: DTE.ExecuteCommand("Build.Cancel", "")
31: 'output a more informative error message to the build pane
32: OW.OutputWindowPanes.Item("Build").OutputString("*********************************************************************************" + System.Environment.NewLine)
33: OW.OutputWindowPanes.Item("Build").OutputString("******************************** Build Stopped ********************************" + System.Environment.NewLine + System.Environment.NewLine)
34: OW.OutputWindowPanes.Item("Build").OutputString("ERROR IN " & Project & System.Environment.NewLine + System.Environment.NewLine)
35: OW.OutputWindowPanes.Item("Build").OutputString("******************************** Build Stopped ********************************" + System.Environment.NewLine)
36: OW.OutputWindowPanes.Item("Build").OutputString("*********************************************************************************" + System.Environment.NewLine)
37: End If
38: End Sub
39:
40: End Module
Once that is in, I modify the Visual Studio EnvironmentEvents Module and add to that a handler for the OnBuildProjConfigDone event that calls the post build All Stop method:
1: Private Sub BuildEvents_OnBuildProjConfigDone( _
2: ByVal Project As String, _
3: ByVal ProjectConfig As String, _
4: ByVal Platform As String, _
5: ByVal SolutionConfig As String, _
6: ByVal Success As Boolean) Handles _
7: BuildEvents.OnBuildProjConfigDone
8:
9: ' call out to the module when build is completed
10: Call CraigsVSModule.BuildProjConfigDone(Project, ProjectConfig, Platform, SolutionConfig, Success)
11:
12: End Sub
Now, when I perform a full build, if any one of my projects has an error, the compile process will All Stop at the end of that project’s build and let me know exactly where the error happened.
So on those 20+ Assembly builds, I find out a lot sooner that I’ve got an error - which greatly benefits my iterative development style.
Time Elapsed 00:00:00.05 ------ Build started: Project: ProcessingClasses, Configuration: Debug Any CPU ------ C:\clients\[theClient]\ProcessingClasses\Processors\ADPGenericData.cs(433,47): error CS1002: ; expected Compile complete -- 1 errors, 0 warnings Build started 6/28/2010 10:54:27 AM. CoreCompile: C:\Windows\Microsoft.NET\Framework\v4.0.30319\Csc.exe /noconfig /nowarn:1701,1702 ... Build FAILED. Time Elapsed 00:00:00.56 ********************************************************************************* ******************************** Build Stopped ******************************** ERROR IN ..\ProcessingClasses\ProcessingClasses.csproj ******************************** Build Stopped ******************************** ********************************************************************************* Build has been canceled.