0

I've been working on this about 14 hours now. It is totally driving me crazy.

Without referencing any custom dlls I want to walk $dte.Solution.Projects for either projects or projectitems to check if

$SourceControl = get-interface $dte.SourceControl ([EnvDTE.SourceControl])
$SourceControl.IsItemUnderScc()

Things like solution folders get in the way. I've done this just fine in C# repeatedly (and in F#), I just can't seem to do it in powershell. I have done it both (C#) via Dte.Solution and UIHierarchy

My C# walking code is in a T4 Nuget Package as an example, but all my linqpad samples currently use UIHierarchy

Here's a sample from that c# that doesn't seem to work in powershell:

C# Projects projects = dte.Solution.Projects;

Powershell $Projects= [EnvDTE.Projects]$dte.Solution.Projects

which fails with Cannot convert the "System.__ComObject" value of type "System.__ComObject#{e3ec0add-31b3-461f-8303-8a5e6931257a}" to type "EnvDTE.Projects".

Alex
  • 21,273
  • 10
  • 61
  • 73
Maslow
  • 18,464
  • 20
  • 106
  • 193
  • Why do you cast it? $Projects = $dte.Solution.Projects works. – David Brabant May 28 '14 at 14:25
  • well the plan was to stick them in a `System.Collections.Generic.List[EnvDTE.Project]` but apparently if I use `+=` on that object instead of calling `.Add` I don't have to do any casting. is the `+=` adding properties or adding to the `list` in this case? – Maslow May 28 '14 at 14:40

1 Answers1

6

Using the code provided later in this answer calling it for just the first project in your solution would be GetUnversionedFiles(GetProjectFiles((GetSolutionProjects).get_Item(1)))

to run this code GetUnversionedFiles(GetProjectFiles((GetSolutionProjects).get_Item(0)))


Get the projects in the solution

function GetSolutionProjects(){
    $projects = get-interface $dte.Solution.Projects ([EnvDTE.Projects])
    write-debug "projects=$projects"
    $result = new-object "System.Collections.Generic.List[EnvDTE.Project]"
    foreach($project in $projects.GetEnumerator()) {
            if($project -eq $null){
                continue;
            }

            write-debug "yay project or solution folder! $project $project.Kind"
            if($project.Kind -eq [EnvDTE80.ProjectKinds]::vsProjectKindSolutionFolder){
                write-debug ("Solution folder "+$project.Name)

                foreach($solutionFolderProject in RecurseSolutionFolderProjects($project)){
                    $result+=$solutionFolderProject
                }

            } else {
                write-debug ("else " +$project.Name +  " " + $project.Kind
                $result+=$project
            }
    }
    return $result
}

recurse down solution folders

function RecurseSolutionFolderProjects(){
    param($solutionFolder = $(throw "Please specify a solutionFolder"))
    $projectList = @()
    for($i = 1; $i -le $solutionFolder.ProjectItems.Count; $i++){
        $subProject = $solutionFolder.ProjectItems.Item($i).subProject
        if($subProject -eq $null){
            continue;
        }

        if($subProject.Kind -eq [EnvDTE80.ProjectKinds]::vsProjectKindSolutionFolder)
        {
            $projectList += RecurseSolutionFolderProjects($subProject)
        } else {
            $projectList += $subProject
        }
    }
    return $projectList
}

walk down projectItems

function RecurseDescendants(){
    param($source  = $(throw "Please specify a source"))
    write-debug "starting RecurseDescendants"
    $result = new-object "System.Collections.Generic.List[EnvDTE.ProjectItem]"
    foreach($s in $source){
        #write-host "working on " $s.Kind $s.Name $s.FileNames(0)

        $pi = $s.Object -as [EnvDTE.ProjectItem]
        $result+=$s
        $children=$s.ProjectItems
        foreach($child in RecurseDescendants($children)){
            $result+=$child
        }
        write-debug "inner for each stopped"
    }
    write-debug "outer for each finished"
    return $result
}

walk project for files within

function GetProjectFiles(){
    param($project = $(throw "Please specify a project"))

    write-debug ("getting project files for " + $project.Name + " "+ $project.ProjectName)

    $projectItems = RecurseDescendants($project.ProjectItems)
        return $projectItems | Where-Object {$_.Kind -ne [EnvDTE.Constants]::vsProjectItemKindPhysicalFolder}
    }

Check found files for being in version control

    function GetUnversionedFiles(){
        param($items = $(throw "Please specify items"))
        write-host "checking for unversioned files"

        $SourceControl = get-interface $dte.SourceControl ([EnvDTE.SourceControl])
        return $items | Where-Object {$SourceControl.IsItemUnderSCC($_.FileNames(0)) -eq $FALSE }

    }

walk project for items within

function GetProjectItems(){ 
    param($project = $(throw "Please specify a project"))
    if($project.ProjectItems.count -gt 0){
        write-debug "getting project items for '$project.Name' '$project.ProjectName'"
    }
    #example: GetProjectItems((GetSolutionProjects).get_Item(1))
    $result =RecurseDescendants($project.ProjectItems)
    return $result
}

the most current version is at https://github.com/ImaginaryDevelopment/config/blob/master/My%20Documents/WindowsPowerShell/NuGet_profile.ps1

Maslow
  • 18,464
  • 20
  • 106
  • 193