【问题标题】:Is there an easy way to add multiple projects to a solution?有没有一种简单的方法可以将多个项目添加到解决方案中?
【发布时间】:2019-04-19 16:11:24
【问题描述】:

在某些解决方案中,我在开发期间使用对内部项目的直接引用,并切换到 nuget 引用进行发布。但是,手动将 30 多个项目添加到新解决方案中是一项乏味的任务。

我想知道是否有更快的方法来做到这一点。对于项目,这很容易,因为您只需复制/粘贴 xml,但解决方案文件并不那么容易编辑,但也许有一些技巧?

【问题讨论】:

  • @AhmadIbrahim 当然,但它不像 *.sln 格式像 *.csproj 文件那样具有自我解释性。有了所有guids,编辑什么内容非常令人困惑:|
  • 我还没有听说有任何视觉工作室扩展可以帮助解决这个问题。手动编辑 SLN 文件可能与通过 VS 手动编辑一样多或更多。您必须打开每个 csproj 并归档 GUID 并将其与路径一起输入 SLN,并在 SLN 中设置任何构建配置。也许创建一个脚本并使其开源?
  • 你能用 2 个独立的 SLN 文件完成你想要的吗?还是单独的解决方案配置?
  • @JamesFaix 我会......你认为有一个 API 可以在这样的脚本中使用吗?

标签: c# visual-studio solution sln-file


【解决方案1】:

我基于@JamesFaix 链接对visualstudio 的可扩展性进行了一些研究,并设法将这段代码组合在一起:

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
  • 我也放到了GitHub上,是here
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多