【问题标题】:How to create nested Solution Folders with envdte如何使用 envdte 创建嵌套的解决方案文件夹
【发布时间】:2018-08-05 20:47:19
【问题描述】:

我尝试通过 Powershell (envdte) 创建具有嵌套解决方案文件夹的 Visual Studio 解决方案。一切都工作到 1 级深,但嵌套解决方案文件夹似乎不起作用(接口为空)。这个问题在这个 SO 问题中描述:

Creating a tree of Solution Folders using DTE and Package Manager Console

很遗憾,这个问题还没有得到解答。我已经联系了那个问题的发帖人,但他在他的解决方案中采取了另一条路线,所以这个问题仍然悬而未决。

我的代码摘录。 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(即 Foundation)
  • ModuleGroupFolder(可选)
  • 项目文件夹
  • 项目文件

这是一个嵌套结构。在没有 ModuleGroupFolder 的情况下一切正常,但是当结构具有 ModuleGroupFolder 时,由于 Get-Interface 的结果为空,它会导致错误。我已经确认找到了正确的解决方案文件夹。只是变量 $moduleGroupNameFolderInterface 为空。 参数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} 的嵌套解决方案文件夹时,它还不是正确的对象。您必须使用找到的项目中的对象。

【问题讨论】:

    标签: powershell envdte


    【解决方案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
    }
    

    请参考Solution Hierarchy回答,上面的功能解释清楚了

    您可以从GitHub Link获取最新版本

    希望对你有帮助。

    【讨论】:

    • 感谢您的回复。我不太明白这将如何解决铸造找到的解决方案文件夹(使用Get-Interface)不会为空的问题。我可以找到解决方案文件夹,但无法将其转换为正确的类型并在其上使用 AddSolutionFolder。您的解决方案是否解决了这个问题?
    • 并非如此。然后你需要显式地转换它。我还没有看到你的结构如此难以分辨。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多