以编程方式构建msbuild 15项目

rep*_*pka 13 c# msbuild c#-7.0 visual-studio-2017

我正在尝试构建一个使用VS2017创建的简单C#7类库项目.

框架程序集中的MSBuild已过时,所以我正在引用Microsoft.Build,Microsoft.Build.EngineMicrosoft.Build.Framework从visual studio(C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin)中的MSBuild文件夹中引用.

不过,当我这样做时:

using (var collection = new ProjectCollection())
{
    var proj = collection.LoadProject(@"c:\projects\Sample\Sample.csproj"); // <-- exception
    proj.Build(new[] {new ConsoleLogger()});
}
Run Code Online (Sandbox Code Playgroud)

我越来越 InvalidProjectFileException: The tools version "15.0" is unrecognized. Available tools versions are "4.0", "2.0".

是否有使用最新构建工具和C#7编译器调用构建的编程方法?

Vil*_*mir 4

我的团队也有类似的需求,因此我为 C# 编写了一个支持多个版本的 Visual Studio 的生成器库。我无法使Project.Build功能正常工作,所以我直接执行MsBuild.exe。

我是如何构建它的:

使用NuGet中的 Microsoft.Build.Framework

创建一个新的 Project 对象,其中包含 1 个名为 Build 的目标

定义正确的工具版本

根据 Visual Studio 版本的项目:

  • 2010、2012 => 4.0
  • 2013 => 12.0
  • 2015 => 14.0
  • 2017 => 15.0

添加类型为 MsBuild 的新任务

项目属性包含我需要构建的所有项目

定义工具版本

与项目具有相同值的 MsBuild 任务

将项目序列化到临时文件中

根据ToolsVersion找到正确的MsBuild.exe

4.0、12.0、14.0

在注册表中发现:

Registry.LocalMachine.OpenSubKey($@"SOFTWARE\Microsoft\MSBuild\ToolsVersions\{msBuildVersion}")
Run Code Online (Sandbox Code Playgroud)

15.0

不再在注册表中,需要使用Nuget包Microsoft.VisualStudio.Setup.Configuration.Interop

        var query = new SetupConfiguration();

        var query2 = (ISetupConfiguration2)query;

        var e = query2.EnumAllInstances();

        var helper = (ISetupHelper)query;

        int fetched;

        var instances = new ISetupInstance[1];

        do
        {
            e.Next(1, instances, out fetched);
            if (fetched > 0)
            {
                var instance = instances[0];

                var instance2 = (ISetupInstance2)instance;

                var state = instance2.GetState();

                // Skip non-complete instance, I guess?
                // Skip non-local instance, I guess?
                // Skip unregistered products?
                if (state != InstanceState.Complete
                    || (state & InstanceState.Local) != InstanceState.Local
                    || (state & InstanceState.Registered) != InstanceState.Registered)
                {
                    continue;
                }

                var msBuildComponent =
                    instance2.GetPackages()
                        .FirstOrDefault(
                            p =>
                                p.GetId()
                                    .Equals("Microsoft.Component.MSBuild",
                                        StringComparison.InvariantCultureIgnoreCase));

                if (msBuildComponent == null)
                {
                    continue;
                }

                var instanceRootDirectory = instance2.GetInstallationPath();

                var msbuildPathInInstance = Path.Combine(instanceRootDirectory, "MSBuild", msBuildVersion, "Bin", "msbuild.exe");

                if (File.Exists(msbuildPathInInstance))
                {
                    return msbuildPathInInstance;
                }
            }
        } while (fetched > 0);
Run Code Online (Sandbox Code Playgroud)

执行MsBuild.exe

并使用自定义 XML 记录器构建序列化项目 - 您可以使用MsBuildExtensionPack提供的记录器

阅读结果摘要

从 Xml 反序列化结果摘要并使用它来确定构建是否失败、发生了哪些错误和警告等。