I no longer work at Microsoft, so please don't bother leaving a comment here or trying to contact me through my MSDN blog.
You can find my new blog at http://www.technologytoolbox.com/blog/jjameson. My new site also provides copies of all posts from my MSDN blog.
As promised in a post last week, here are the macros that I use to quickly unload or reload dozens of projects in a large Visual Studio solution. Hmmm, perhaps effortlessly is a better word choice -- considering I might need to wait 30 seconds or so for all of the projects to unload or reload.
Here is my UnloadAllProjects() macro:
UnloadAllProjects()
Public Sub UnloadAllProjects() If (DTE.Solution Is Nothing _ Or DTE.Solution.Count = 0) Then MessageBox.Show( _ "Cannot unload all projects because no solution is open.", _ "Error", _ MessageBoxButtons.OK, _ MessageBoxIcon.Error) Exit Sub End If Dim solutionName As String = _ DTE.Solution.Properties.Item("Name").Value.ToString() WriteOutput("Unloading projects in solution (" & solutionName & ")...") Dim solutionExplorer As Window = _ DTE.Windows.Item(Constants.vsWindowKindSolutionExplorer) solutionExplorer.Activate() Dim solutionHierarchy As UIHierarchy = solutionExplorer.Object For Each proj As Project In DTE.Solution.Projects ' Note that the project may be a solution folder, in which case we ' want to unload all of the projects within the solution folder. ' ' Also note if the project is already unloaded, or is a solution ' folder containing no projects -- then a COM exception occurs. Try UnloadProject(proj, solutionName, solutionHierarchy) Catch ex As Exception WriteOutput("Error unloading project (" & proj.Name & "): " _ & ex.Message) End Try Next WriteOutput("Successfully unloaded projects in solution (" _ & solutionName & ").") End Sub
The actual work of unloading a project is delegated to the UnloadProject() method:
UnloadProject()
Private Sub UnloadProject( _ ByVal proj As Project, _ ByVal solutionName As String, _ ByVal solutionHierarchy As UIHierarchy) Debug.Assert(Not proj Is Nothing) Debug.Assert(String.IsNullOrEmpty(solutionName) = False) Debug.Assert(Not solutionHierarchy Is Nothing) WriteOutput("Unloading project (" & proj.Name & ")...") If (proj.Kind = Constants.vsProjectKindMisc) Then ' "Miscellaenous Files" cannot be unloaded WriteOutput("Project (" & proj.Name & ") cannot be unloaded.") Return End If Dim projPath As String = solutionName & "\" & proj.Name Dim obj As Object = solutionHierarchy.GetItem(projPath) obj.Select(vsUISelectionType.vsUISelectionTypeSelect) Dim projectName As String = proj.Name DTE.ExecuteCommand("Project.UnloadProject") WriteOutput("Successfully unloaded project (" & projectName & ").") End Sub
A few interesting notes...
DTE.ExecuteCommand("Project.UnloadProject")
WriteOutput()
If you take the above code and essentially search-and-replace "unload" with "reload" then you will end up with my macro to reload all projects within the solution:
Public Sub ReloadAllProjects() If (DTE.Solution Is Nothing _ Or DTE.Solution.Count = 0) Then MessageBox.Show( _ "Cannot reload all projects because no solution is open.", _ "Error", _ MessageBoxButtons.OK, _ MessageBoxIcon.Error) Exit Sub End If Dim solutionName As String = _ DTE.Solution.Properties.Item("Name").Value.ToString() WriteOutput("Reloading projects in solution (" & solutionName & ")...") Dim solutionExplorer As Window = _ DTE.Windows.Item(Constants.vsWindowKindSolutionExplorer) solutionExplorer.Activate() Dim solutionHierarchy As UIHierarchy = solutionExplorer.Object For Each proj As Project In DTE.Solution.Projects ' Note that the project may be a solution folder, in which case we ' want to reload all of the projects within the solution folder. ' ' Also note if the project is already loaded, or is a solution ' folder containing no projects -- then a COM exception occurs. Try ReloadProject(proj, solutionName, solutionHierarchy) Catch ex As Exception WriteOutput("Error reloading project (" & proj.Name & "): " _ & ex.Message) End Try Next WriteOutput("Successfully reloaded projects in solution (" _ & solutionName & ").") End Sub Private Sub ReloadProject( _ ByVal proj As Project, _ ByVal solutionName As String, _ ByVal solutionHierarchy As UIHierarchy) Debug.Assert(Not proj Is Nothing) Debug.Assert(String.IsNullOrEmpty(solutionName) = False) Debug.Assert(Not solutionHierarchy Is Nothing) WriteOutput("Reloading project (" & proj.Name & ")...") If (proj.Kind = Constants.vsProjectKindMisc) Then ' "Miscellaenous Files" cannot be unloaded WriteOutput("Project (" & proj.Name & ") cannot be unloaded.") Return End If Dim projPath As String = solutionName & "\" & proj.Name Dim obj As Object = solutionHierarchy.GetItem(projPath) obj.Select(vsUISelectionType.vsUISelectionTypeSelect) DTE.ExecuteCommand("Project.ReloadProject") WriteOutput("Successfully reloaded project (" & proj.Name & ").") End Sub
Like I mentioned earlier, unloading or reloading all of the projects within a solution is not exactly an instantaneous operation. However, when you consider the incremental build time saved by unloading all of the projects in a large solution except for the few you are working on at any given time, you definitely come out far ahead in the end. You'll be amazed at how much more productive you can be when your solution containing 50+ projects incrementally builds in just a few seconds when all but a handful of the projects are unloaded.
I hope you find these macros as helpful as I have over the years.
Perhaps in a future version of Visual Studio, we'll have the ability to right-click the solution in Solution Explorer and then click something like Unload Projects in Solution (similar to the Unload Projects in Solution Folder option that is currently available -- but only for solution folders, not the solution itself). Until then, I don't see me giving up my dependency on these macros anytime soon.