Enumerating projects in a Visual Studio solution

People writing add-ins for Visual studio probably have come across the nightmare of the Visual studio object model to go through the projects within a solution. I had to get the list of projects in a solution, and for each solution its output path in the current configuration. Although I need the code in C# later on, the best way to check out how to program against the Visual Studio object model is within the Macro IDE of Visual Studio (Tools->Macros->Macros IDE).

Although the question seems quite straightforward, the trouble begins when you have Solution Folders containing projects. The Solution object has a property called Projects, but Solution Folders are also seen as Projects. A project has project items. A project item can be a folder, a file, or... a project. You have to see it to believe the mess.

After a lot of trial and error I got to a solution where I check if a project item has its ConfigurationManager property set, if this is the case, it must be a project. Not sure if this is the best approach, but it works for me. For example for the following project structure using Solution Folders:

I get the following output:

And the code to accomplish this (paste in  Macros IDE):

Sub SolutionProjects()
        Dim project As EnvDTE.Project
        Write("--------- DUMP OF ALL PROJECTS IN CURRENT SOLUTION -------------")
        Try
            If Not DTE.Solution.IsOpen Then
                Write("There is no solution open.")
            Else
                For Each project In DTE.Solution.Projects
                    NavProj(project)
                Next
            End If
        Catch ex As System.Exception
            Write(ex.ToString)
        End Try
    End Sub
    Sub NavProj(ByVal proj As Project)
        Dim outputPathProperty As EnvDTE.Property
        Dim outputPath As String

If Not (proj.ConfigurationManager Is Nothing) Then ' It's a project! outputPathProperty = _ proj.ConfigurationManager.ActiveConfiguration.Properties.Item("OutputPath") If outputPathProperty Is Nothing Then outputPath = "<no output path set>" Else outputPath = outputPathProperty.Value End If Write("### Project: " + proj.Name + ", OutputPath: " + outputPath) Else NavProjItems(proj.ProjectItems) End If End Sub Sub NavProjItems(ByVal projItems As ProjectItems) Dim projectItem As EnvDTE.ProjectItem

    <span style="color: rgb(0,0,255)">If</span> <span style="color: rgb(0,0,255)">Not</span> (projItems <span style="color: rgb(0,0,255)">Is</span> <span style="color: rgb(0,0,255)">Nothing</span>) <span style="color: rgb(0,0,255)">Then

For Each projectItem In projItems If Not (projectItem.SubProject Is Nothing) Then ' Recurse, can be an Enterprise project in ' Visual Studio .NET 2002/2003 or a solution folder in VS 2005 NavProj(projectItem.SubProject) End If Next End If End Sub

Sub Write(ByVal s As String) Dim out As OutputWindowPane = GetOutputWindowPane("MACRO OUTPUT", True) out.OutputString(s) out.OutputString(vbCrLf) End Sub
Function GetOutputWindowPane(ByVal Name As String, Optional ByVal show As Boolean = True) As OutputWindowPane Dim win As Window = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput) If show Then win.Visible = True Dim ow As OutputWindow = win.Object Dim owpane As OutputWindowPane Try owpane = ow.OutputWindowPanes.Item(Name) Catch e As System.Exception owpane = ow.OutputWindowPanes.Add(Name) End Try owpane.Activate() Return owpane End Function

10 Comments

  • Works great - thanks!

  • thanks for da code but da problem we r havin is that we need to find the current solutins thats opened..

    coz da DTE object only takes the first opened solution ignoring the others..

    can u help us..

    chamira2001@yahoo.com

  • Hi Serge,

    Great post!
    But I have a question: if you have a Projects object, you enumerate the Project Objects with a foreach loop.
    Do you know how to use the Projects.Item function? I cant seem to get it to work.

    Thanks!

    Joris

  • thanks, very helpful. FYI, I used the Project.Kind property to determine if a project was a solution folder, looking for this guid: {66A26720-8FB5-11D2-AA7E-00C04F688DDE}. That worked for us.

  • I am unable to read a web project project items using the following:

    Dim oSol As Solution
    Dim oPrj As Project
    Dim oPrjItem As ProjectItem
    Dim oSolType As Type = Type.GetTypeFromProgID(psVSVersion)
    oSol = CType(Activator.CreateInstance(oSolType), Solution)
    oSol.Open(psSolutionPath)

    The code line oSol.Projects.Item(1).Object returns nothing and I'm unable to read the project. The project read is a web project.

  • Great post! Really helpful for me, looking for method for enumerating projects in solution folders in VS2005. Thanks.

  • great! saved my time!!

  • I stumbled upon this via StackOverflow and tried out your solution in a VS 2010 solution. Guess what - it still works!!

    I agree its a mess - having solution folders list out as Projects and this weird check to see if they are actual projects.

    But hey, thanks for finding that out!!

  • Что для Вас Юмор?
    фотографии и видео cверхестественных чудес и знамений и силы

  • ab8EVR This is one awesome article post. Really Cool.

Comments have been disabled for this content.