It seems as though I've dropped off from blogging, and that surely was not my intention. So without further ado, let's jump into another useful piece of code. People have been asking for this feature for quite some time now, and I'll be sure to push for it to be built-in to our next release. In the meantime, it's a devastatingly simple macro :) Just to clarify, here is the problem: while coding in Visual Studio, you may find that you only want to compile a project, instead of the entire solution. To this effect, there are a set of Build/Rebuild/Clean commands for the current project. However, the issue is that the commands apply to the current project. What is that anyway? It's the project corresponding to the file currently active in the editor. Crazy? It makes sense for a whole bunch of cases, but obviously not all. A lot of times, what users really want is to Build/Rebuild/Clean the startup project. And thus the following 3 macros.

    Sub BuildStartupProject()

        Dim sb As SolutionBuild = DTE.Solution.SolutionBuild

        Dim projName As String = sb.StartupProjects(0)

        sb.BuildProject(sb.ActiveConfiguration.Name, projName, False)

    End Sub

 

Wait a sec. Didn't I just say I'd provide 3 macros? One for each command: Build, Rebuild and Clean? I did. But as I was coding these macros, I discovered an unfortunate deficiency in our current Extensibility API. We only provide a BuildProject function, and none of the other two. Until this is fixed, we can write the following hacky macros... 

 

    Sub CleanStartupProject()

        Dim sb As SolutionBuild = DTE.Solution.SolutionBuild

        Dim startupProjectName As String = sb.StartupProjects(0)

        Dim solContexts As SolutionContexts = sb.ActiveConfiguration.SolutionContexts

        Dim stateDic As Dictionary(Of String, Boolean) = New Dictionary(Of String, Boolean)

 

        ' save current build states

        For Each scon As SolutionContext In solContexts

            stateDic(scon.ProjectName) = scon.ShouldBuild

            If scon.ProjectName.Equals(startupProjectName) Then

                scon.ShouldBuild = True

            Else

                scon.ShouldBuild = False

            End If

        Next

 

        ' clean "solution" with only one project enabled

        sb.Clean(True)

 

        ' restore previous state

        For Each scon As SolutionContext In solContexts

            scon.ShouldBuild = stateDic(scon.ProjectName)

        Next

    End Sub

 

 

    Sub RebuildStartupProject()

        Dim sb As SolutionBuild = DTE.Solution.SolutionBuild

        Dim startupProjectName As String = sb.StartupProjects(0)

        Dim solContexts As SolutionContexts = sb.ActiveConfiguration.SolutionContexts

        Dim stateDic As Dictionary(Of String, Boolean) = New Dictionary(Of String, Boolean)

 

        ' save current build states

        For Each scon As SolutionContext In solContexts

            stateDic(scon.ProjectName) = scon.ShouldBuild

            If scon.ProjectName.Equals(startupProjectName) Then

                scon.ShouldBuild = True

            Else

                scon.ShouldBuild = False

            End If

        Next

 

        ' clean "solution" with only one project enabled

        sb.Clean(True)

        sb.Build(True)

 

        ' restore previous state

        For Each scon As SolutionContext In solContexts

            scon.ShouldBuild = stateDic(scon.ProjectName)

        Next

    End Sub

 

What these virtually identical macros do is Clean/Rebuild the entire solution but I temporarily mark all projects not to be built, save for the startup project. There you have it. The remaining flaw is my assumption that you only use a single startup project, while VS supports multiple...