Recursively traversing a Visual Studio Solution us

2019-04-14 15:15发布

问题:

I need to programatically extract information from a solution which contains almost 150 projects in it. The solution file is not flat though, so some of the projects are organized into folders, the folder hierarchy can be more levels deep. This fits a recursive solution: I could write a function, which enumerates a list, and if the element is a project it would examine it, if it is a folder it would go into the folder and recursively call itself to examine the folder's content. The gist of it:

$dte = [System.Runtime.InteropServices.Marshal]::GetActiveObject("visualstudio.dte.11.0")

function traverseproject {
    param([object]$prjnode, [int]$level)
    if ($prjnode.Kind -eq "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}")
    {
        Write $prjnode.Name
        Write $level
    }
    if ($prjnode.Kind -eq "{66A26720-8FB5-11D2-AA7E-00C04F688DDE}")
    {
        foreach ($prjsubnode in $prjnode)
        {
            traverseproject($prjsubnode, $level + 1)
        }
    }
}

foreach($prjn in $dte.solution.projects)
{
    traverseproject($prjn, 0)
}

The problem is that the $prjnode object what the recursive function gets is weird. Write $prjnode.Name doesn't output anything. Probably for the same reason I cannot iterate through the nodes of the folder object. Right now in the code above it's foreach ($prjsubnode in $prjnode), that just doesn't do anything silently. I tried foreach ($prjsubnode in $prjnode.ProjectItems), that gives error. I tried any kind of combinations.

From the error messages it seems that the $prjnode is type of a DTE ProjectItem link, 8E2F1269-185E-43C7-8899-950AD2769CCF. I can print out the Count property and it seems valid, but I don't see any property on the interface where I could get a hold of the contained elements. So maybe that's why I cannot iterate through? There's no way? I see the Visual Basic example at the bottom of the MSDN page I linked, but I need a working PowerShell solution.

The first call of the function seems to work OK, for example it sees the $prjnode.Kind property, but after the first recursive call things are lost.

回答1:

Since you're already loading the dte, Check out http://studioshell.codeplex.com/

The feature that helps you the most:

  • Manage your projects, references, breakpoints, stack frame locals, menus, toolbars, Visual Studio settings, IDE windows, and even your code from PowerShell scripts, all in a consistent and discoverable way.


回答2:

Here is how you can get all loaded projects with StudioShell

$projects = ls -path "DTE:\solution\Projects" -recurse
  | where {$_.FileName -match ".csproj"}

Note that it may take up to 15 minutes for big solutions.