Как создать вложенные папки решений с помощью envdte

Я пытался создать визуальное студийное решение с вложенными папками решений через Powershell (envdte). Все работает до 1 уровня, но вложение папки решения, похоже, не работает (интерфейс пуст). Проблема описана в этом вопросе SO:

Создание дерева папок решений с использованием DTE и консоли диспетчера пакетов

К сожалению, на этот вопрос еще не ответили. Я обратился к автору этого вопроса, но он выбрал другой путь в рамках своего решения, поэтому вопрос все еще открыт.

Выдержка из моего кода. Метод Find-Solution находит папку решений, которую я ищу в данном контексте (= startfolder). Когда найден, он возвращает этот элемент:

function Find-SolutionFolder {
    Param($SearchedFolderName, $StartFolder)

    Write-Output "number " $StartFolder.ProjectItems.Count
    For ($i = 1; $i -le $StartFolder.ProjectItems.Count; $i++) {
        $Item = $StartFolder.ProjectItems.Item($i)

        if ($Null -Eq $Item.Object) {
            continue;
        }

        if ($Item.Object.Kind -eq [EnvDTE80.ProjectKinds]::vsProjectKindSolutionFolder) {
            if ($Item.Name -Eq $SearchedFolderName) {
                return $Item
            }
            Find-SolutionFolder $SearchedFolderName $Item
        }
    }
}

Метод Add-Projects заботится о сохранении структуры в решении. Структура является:

  • Решение
  • ModuleTypeFolder (т. Е. Основание)
  • ModuleGroupFolder (необязательно)
  • Папка для проекта
  • projectfiles

Это вложенная структура. Все работает без ModuleGroupFolder, но когда структура имеет ModuleGroupFolder, это вызывает ошибку из-за нулевого результата Get-Interface. Я подтвердил, что найдена правильная папка решения. Просто переменная $moduleGroupNameFolderInterface имеет значение null. Параметр modulePath - это путь на диске

function Add-Projects {
    Param(
        [Parameter(Position = 0, Mandatory = $True)]
        [string]$ModulePath
    )

    Write-Output "Adding project(s)..."

    # For the sake of the example always use a folder named 'Foundation'
    $moduleTypeFolder = Get-FoundationSolutionFolder

    # When the literal 'Foundation' solution folder does not exist in the solution it will be created.
    if (-Not $moduleTypeFolder) {
        $dte.Solution.AddSolutionFolder($config.ModuleType)
        $moduleTypeFolder = Get-ModuleTypeSolutionFolder
    }
    $moduleTypeFolderInterface = Get-Interface $moduleTypeFolder.Object ([EnvDTE80.SolutionFolder])

    # Add ModuleGroup Folder if needed
    if (-Not [string]::IsNullOrWhiteSpace($config.ModuleGroupName)) {
        $moduleGroupNameFolder = Find-SolutionFolder $config.ModuleGroupName $moduleTypeFolder
        if (-Not $moduleGroupNameFolder) {
            $moduleTypeFolderInterface.AddSolutionFolder($config.ModuleGroupName)
            $moduleGroupNameFolder = Find-SolutionFolder $config.ModuleGroupName $moduleTypeFolder
        }
        $moduleGroupNameFolderInterface = Get-Interface $moduleGroupNameFolder.Object ([EnvDTE80.SolutionFolder])
        if ($Null -eq $moduleGroupNameFolderInterface) {
            Write-Output "moduleGroupNameFolderInterface is null; this is wrong"
        } else {
            $moduleNameFolder = $moduleGroupNameFolderInterface.AddSolutionFolder($config.ModuleName)
            $moduleNameFolderInterface = Get-Interface $moduleNameFolder.SubProject ([EnvDTE80.SolutionFolder])
            # Search in the new module folder for csproj files and add those to the solution.
            Get-ChildItem -File -Path $ModulePath -Filter "*$csprojExtension" -Recurse | ForEach-Object { $moduleNameFolderInterface.AddFromFile("$($_.FullName)")}
        }
    } else {
        $moduleNameFolder = $moduleTypeFolderInterface.AddSolutionFolder($config.ModuleName)
        $moduleNameFolderInterface = Get-Interface $moduleNameFolder.Object ([EnvDTE80.SolutionFolder])
        # Search in the new module folder for csproj files and add those to the solution.
        Get-ChildItem -File -Path $ModulePath -Filter "*$csprojExtension" -Recurse | ForEach-Object { $moduleNameFolderInterface.AddFromFile("$($_.FullName)")}
    }

    Write-Output "Saving solution..."
    $dte.Solution.SaveAs($dte.Solution.FullName)
}

Заметка. пример не оптимизирован (т.е. дублированный код)

Кто-нибудь может помочь мне решить проблему.

Обновление - ответь на вопрос, я наконец разобрался. Очевидно, что при поиске вложенной папки решения, в которой свойство Kind имеет guid {66A26722-8FB5-11D2-AA7E-00C04F688DDE}, это еще не правильный объект. Вы должны использовать объект в найденном предмете.

1 ответ

В общем, вы ищете рекурсию. Вы можете повторить как это.

Для папки решений:

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
}

Для файлов проекта:

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}
    }

Для элементов проекта:

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
}

Обратитесь к ответу " Иерархия решений", где описанные выше функции четко объяснены

Вы можете получить последнюю версию с этой ссылки GitHub

Надеюсь, поможет.

Другие вопросы по тегам