以编程方式构建 msbuild 15 项目

2024-01-06

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

框架程序集的 MSBuild 已经过时了,所以我引用Microsoft.Build, Microsoft.Build.Engine and Microsoft.Build.Framework来自 Visual Studio 中的 MSBuild 文件夹(C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin).

不过,当我这样做时:

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

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

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


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

我是如何构建它的:

使用 Microsoft.Build.Framework 从NuGet https://www.nuget.org/packages/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}")

15.0

不再在注册表中,需要使用Nuget包Microsoft.VisualStudio.Setup.Configuration.Interop https://www.nuget.org/packages/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);

执行MsBuild.exe

并使用自定义 XML 记录器构建序列化项目 - 您可以使用由MsBuild扩展包 https://github.com/mikefourie/MSBuildExtensionPack

阅读结果摘要

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

以编程方式构建 msbuild 15 项目 的相关文章

  • 类库的 app.config 中的绑定重定向有什么作用吗?

    我经常使用的 VS 解决方案包括单个可执行项目 控制台应用程序 网络应用程序 和许多类库项目这些都被可执行文件引用 使用 NuGet 并安装包时 经常会出现app config为每个项目创建的文件 通常只包含合并引用程序集版本的绑定重定向列
  • 将委托作为方法参数传递

    我目前正在开发一个 EventManager 类 以确保没有任何事件连接到失效的 WCF 双工客户端 并控制防止从同一客户端到一个事件的多个连接 现在基本上 我所坚持的就是尝试将事件委托传递给一个函数来控制这样的分配 var handler
  • 虚拟调用与类型检查的另一个例子

    Problem 我发誓 每次我脑子里都在想 我应该使用虚拟调用而不是类型检查 例如 if obj is Foo else if obj is Bar 我想出了另一个例子 我不知道如何实现前者 我正在通过串行端口实现分组协议 一些伪代码可以最
  • 用于打印的真实尺寸 WPF 控件

    我目前正在开发一个应用程序 用户可以在画布上动态创建 移动 TextBlock 一旦他们将文本块放置在他们想要的位置 他们就可以按下打印按钮 这将导致 ZPL 打印机打印当前显示在屏幕上的内容 ZPL 命令是通过从每个 TextBlock
  • 如何防止在项目生成期间(由 Visual Studio)缓存外部 MSBuild 文件?

    我的解决方案中有一个项目 它最初是一个 C 库项目 它对代码没有任何兴趣 它只是用作我的解决方案中其他项目的依赖项 以确保首先构建它 构建此项目的副作用之一是创建共享的 AssemblyInfo cs 其中包含其他项目正在使用的版本号 我通
  • 在 C++ 中将浮点值作为数组中的索引

    浮点值可以用作数组的索引吗 如果用作索引的表达式生成浮点值 会发生什么情况 float 值将被转换为 int 根据编译器的警告级别 它可能会给出警告或错误 s1 q 12 2 same as q 12 s2 q 12 999999 same
  • 检查 ASP.NET Web 应用程序在运行时是否处于调试模式的首选方法?

    在编译时我可以做这样的检查 if DEBUG Log something endif 但最好检查一下是否debug false 是在运行时在 Web config 中设置的吗 HttpContext IsDebuggingEnabled h
  • 为什么“扔”和“扔前”在这种情况下有相同的行为?

    我惊呆了 我一直以为throw单独在 catch 块中会抛出手头的异常而不改变堆栈跟踪 但是throw ex在 catch 块中将更改堆栈跟踪以显示源自语句位置的异常 采取以下两个代码块 我希望输出会略有不同 因为使用throw和其他用途t
  • 无法加载 DLL“tensorflow”或其依赖项之一(ML.NET)

    我有一个用于图像分类的 NET Core 3 应用程序 使用 Microsoft 的 ML NET 框架 在我的开发机器上 我可以运行代码并且一切正常 但是 当我将其部署到临时服务器时 我在运行时收到此错误 System Reflectio
  • 友元模板特化声明中不允许使用 Constexpr 吗?

    我正在移植 C 14 constexpr代码库从 Clang 到最新的 g 5 1 考虑以下本土开发的简化代码片段bitset自 Clang 3 3 的太平岁月以来 现在已经快 2 年了 该类就一直可以正确编译 include
  • 如何在 .NET 中使 ComboBox 不可编辑?

    我想要一个 仅选择 ComboBox它提供了一个项目列表供用户选择 应在文本部分禁用打字ComboBox控制 我最初对此进行谷歌搜索 发现了一个过于复杂 误导性的建议来捕捉KeyPress event 要使 ComboBox 的文本部分不可
  • 如何从 Visual Studio 2012 导出 C# 应用程序以在其他计算机上运行?

    我刚刚在 Visual Studio 2012 中制作了我的第一个 C 应用程序 我想以某种方式导出它 以便其他人可以在他们的计算机 包括没有 Visual Studio 2012 的计算机 中使用它 我该怎么做 我是 C 新手 找不到任何
  • Outlook VSTO 添加上下文菜单项

    我正在尝试将菜单项添加到附件上下文菜单 问题是该项目没有显示 我看过一些例子 他们说这段代码应该可以工作 this Application AttachmentContextMenuDisplay new ApplicationEvents
  • 抽象类、构造函数和 Co

    嗯 我正在尝试重用 C 代码的一部分 它是一个带有UDP服务器的抽象类 可以在这里看到 http clutch inc com blog p 4 http clutch inc com blog p 4 我创建了一个像这样的派生类 publ
  • SerialPort.Read(byte[], int32, int32) 不是阻塞的,但我想要它 - 我该如何实现?

    我正在编写一个用于与测试设备通信的接口 设备通过串行端口进行通信 并以已知的字节数响应我发送的每个命令 我当前的结构是 发送命令 读回指定字节数 继续申请 但是 当我使用 SerialPort Read byte int32 int32 时
  • 从 C# 2.0 中的 dll 获取命名空间、类名

    我将动态获取dll 我需要加载 dll 并获取命名空间 类名来调用方法 方法名称是静态的 它将始终为 OnStart 基本上我需要通过加载 dll 来运行一个方法 有人可以帮忙吗 要加载程序集 您可以这样做 Assembly assembl
  • 反序列化具有相同元素名称但不同属性的 Xml

    我有一些 XML 如下所示
  • 使用 .NET 2.0 解析 JSON

    想要改进这篇文章吗 提供此问题的详细答案 包括引用和解释为什么你的答案是正确的 不够详细的答案可能会被编辑或删除 我有一个用 C 编写的应用程序 带有 NET Framework 2 0 版本 不幸的是 我无法选择更新到较新版本的 NET
  • 为什么这个结构体的大小是32?

    这就是结构 Structure pour communiquer les param tres de traitement travers le MMF struct params traitement mmf int brilliance
  • libtiff 错误:未配置旧式 JPEG 压缩支持

    在 Mac OS X 上使用 libtiff 将 TIFF 转换为 BMP 时 出现以下错误 scannerdata tif Old style JPEG compression support is not configured scan

随机推荐