有没有一种简单的方法将多个项目添加到解决方案中?

7
在一些解决方案中,在开发过程中我使用直接引用内部项目的方式,然后在发布时切换到 nuget 引用。不过,手动将 30 多个项目添加到新解决方案中是一项繁琐的任务。
我想知道是否有更快捷的方法可以完成这个任务。对于项目来说很容易,你只需要复制/粘贴 xml 代码,但解决方案文件并不像那么容易编辑,不过也许有一些技巧?

我没有听说过任何可以帮助解决这个问题的Visual Studio扩展。手动编辑SLN文件可能需要的工作量与通过VS手动完成相同甚至更多。您需要打开每个csproj和文件GUID,并将其输入到SLN中,以及路径,并在SLN中设置任何构建配置。也许可以创建一个脚本并将其开源化? - JamesFaix
你能用两个单独的SLN文件或单独的解决方案配置来实现你想要的吗? - JamesFaix
@JamesFaix 我会...你认为有没有一个API可以在这样的脚本中使用? - t3chb0t
@JamesFaix 噢,我是想着用类似于 AddProjectReference(fileName) 这样的 visual-studio API 在 cmd-line 级别上使用;-] - t3chb0t
1
https://learn.microsoft.com/en-us/visualstudio/extensibility/starting-to-develop-visual-studio-extensions?view=vs-2019 - JamesFaix
显示剩余5条评论
2个回答

3
你可以使用 dotnet 命令行工具。
对于 Linux 系统:
dotnet sln MySolution.sln add **/*.csproj

对于Windows PowerShell:

dotnet sln MySolution.sln add (Get-ChildItem -Recurse *.csproj)

2
这个在Windows上也可以工作!而且时间非常完美,因为我正要更新一些旧的解决方案,这将使它变得轻而易举 ;-] - t3chb0t
对于想要从头开始创建“超级解决方案”的人来说,这也可能很有趣 - 只需在调用“add”命令之前创建一个空解决方案:dotnet new sln --name MySolution - CodeFox

0

我根据 @JamesFaix 的链接进行了一些关于Visual Studio可扩展性的研究,我成功地编写了这个小代码片段:

using System;
using System.IO;
using System.Linq;
using EnvDTE;
using EnvDTE80;

class Program
{
    static void Main(string[] args)
    {
        // VS2019
        var dteType = Type.GetTypeFromProgID("VisualStudio.DTE.16.0", true);
        var dte = (EnvDTE.DTE)System.Activator.CreateInstance(dteType);

        var sln = (SolutionClass)dte.Solution;

        // Solution to add projects to
        sln.Open(@"C:\Projects\MyProject\MySolution.sln");

        // Projects should be added to the "lib" solution-folder.
        var lib = FindSolutionFolderOrCreate(sln, "lib");

        // These projects should be added.
        var projectPaths = new[]
        {
            @"C:\Projects\MyLibs\Lib1.csproj",
            @"C:\Projects\MyLibs\Lib2.csproj"
        };

        foreach (var path in projectPaths)
        {
            var name = Path.GetFileNameWithoutExtension(path);
            // If project not already in the solution-folder then add it.
            if(!(lib.Parent.ProjectItems.Cast<ProjectItem>().Any(pi => pi.Name == name)))
            {
                lib.AddFromFile(path);
            }
        }

        dte.Solution.Close(true);
    }

    private static SolutionFolder FindSolutionFolderOrCreate(SolutionClass sln, string folderName)
    {
        foreach (var x in sln.Projects)
        {
            if (x is Project p && p.Name.Equals(folderName, StringComparison.OrdinalIgnoreCase))
            {
                return (SolutionFolder)p.Object;
            }

        }

        var proj = (sln as Solution2).AddSolutionFolder(folderName);

        return (SolutionFolder)proj.Object;
    }
}

这个程序的

*.csproj 文件:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <!--<TargetFramework>netcoreapp2.2</TargetFramework>-->
    <TargetFramework>net47</TargetFramework>
    <EnableUnmanagedDebugging>true</EnableUnmanagedDebugging>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <DebugType>full</DebugType>
    <DebugSymbols>true</DebugSymbols>
  </PropertyGroup>

  <ItemGroup>
    <Reference Include="EnvDTE">
      <HintPath>..\..\..\..\..\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\PublicAssemblies\envdte.dll</HintPath>
    </Reference>
    <Reference Include="EnvDTE80">
      <HintPath>..\..\..\..\..\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\PublicAssemblies\envdte80.dll</HintPath>
    </Reference>
  </ItemGroup>

</Project>

我在这里使用net47,因为netcoreapp不允许您调试COM对象,这使得它真的是一种痛苦的经历。

您还需要引用两个EnvDTE文件。


你必须承认,这个API真是一团糟。如果没有其他的SE问题,我可能永远都不会发现需要将SolutionClass强制转换为(sln as Solution2) - 真是太难了 :-o - t3chb0t
我也将它放在了GitHub上,链接在这里:https://github.com/he-dev/visual-studio-automation/tree/master/ProjectsInSolutionFolder - t3chb0t
在最新的VS2019上尝试了该代码,但出现了CS1752错误:Interop类型“SolutionClass”无法嵌入。请使用相应的接口。 - galsi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接