【问题标题】:Windows 2016 server with MSBuild for building .NET 4.6.1 project带有 MSBuild 的 Windows 2016 服务器,用于构建 .NET 4.6.1 项目
【发布时间】:2019-11-11 16:38:26
【问题描述】:

我有一台 Windows 2016 服务器,我将其设置为构建服务器。将设置为使用 MSBuild 构建 .NET 4.6.1 Web API 项目我使用的是 MSBuild 版本 15.0,并使用 TeamCity 版本 2018.1,但是我不相信 TeamCity 真的参与了这个问题,因为我得到了这个问题手动/直接针对代码执行 MSBuild

Windows 2016 具有 .NET 4.7,因此我安装了 .NET 4.6.1 目标包和 .NET 4.6.1 SDK。在 TeamCity 的构建步骤中,我有一个 MSBuild 参数“/p:TargetFramework=net461”但是在构建日志中,当我手动/直接针对代码运行 MSBuild 时,我收到以下错误:

HttpExtensions.cs(44, 24): error CS8137: Cannot define a class or member that utilizes tuples because the compiler required type 'System.Runtime.CompilerServices.TupleElementNamesAttribute' cannot be found. Are you missing a reference?

HttpExtensions.cs(44, 24): error CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported

当我在安装了 Visual Studio 2017 的开发计算机上时,项目构建没有问题。我的开发机器是Windows 10,但另一个主要区别是Windows 2016服务器没有Visual Studio。我的想法是这与 Windows 2016 的主要 .NET 版本为 4.7 有关,安装 Visual Studio 可能会解决这个问题。但我真的很想避免在 Windows 2016 服务器上安装 Visual Studio

有什么想法/反馈吗?

【问题讨论】:

  • 我不知道 TeamCity,但 Team Foundation Server 需要在构建机器上安装 Visual Studio 才能始终如一地工作。确保两台机器上都安装了相同的框架 sdk 版本。
  • 至于@Eldar。另外,我相信如果您是通过 MS Build 构建的,则需要以正确的顺序获取依赖项,否则它将无法构建。 Visual Studio 构建将解决它,但 MS Build 不会。即使安装了 VS,您也可能需要编辑 .csproj 文件以通过 MS Build 获得正确的构建顺序。无法添加为答案,因为没有看到设置就很难解决。
  • 如果您不想安装 Net,那么您需要发布应用程序并运行使用安装程序创建的 setup.exe 以使应用程序运行。
  • 您使用哪个 MSBuild.exe?考虑在同一台机器上有多个这一事实。
  • 我使用的是 MSBuild 15.0 版。当我运行 MSBuild 时,我专门选择此版本并直接针对产生错误的代码库运行

标签: c# .net msbuild


【解决方案1】:

以下错误中的一个或两个表明您正在尝试使用 ValueTuples,但没有对 System.ValueTuple 的引用或具有 NET 4.7 或更高版本的 mscorlib.dll 版本。

error CS8137: Cannot define a class or member that utilizes tuples because the compiler required type 'System.Runtime.CompilerServices.TupleElementNamesAttribute' cannot be found. Are you missing a reference?  
error CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported  

简单的解决方案是添加对 System.ValueTuple 最新版本的 nuget 引用,然后您的项目将在 NET 4.6.1 中构建。详情请见here

这对您来说在本地工作,但在您的构建机器上不起作用的原因稍微复杂一些(并且完全是理论上的,因为我没有这些规格的机器来测试它)。

请参阅this 问题,了解 MSBuild 在没有可用的正确定位包时如何工作。

您的构建机器正在按要求构建您的项目。 MSBuild 15.0 发现它需要构建一个以 NET 4.6.1 为目标的项目,找到正确的目标包 / SDK 并引入对 NET 4.6.1 mscorlib.dll 的引用,并正确地发现这个 dll 它没有引用到 ValueTuples 并且无法构建您的项目。

我的猜测是(我很高兴在这里错了)您的本地计算机上没有安装 Net 4.6.1 的目标包/SDK,因此 msbuild 默认为与 15.0 关联的 NET 框架这是(我认为)NET 4.7。这意味着使用的 mscorlib.dll 是 NET 4.7 的,它确实包含一个内置的 ValueTuple 类型。

通常添加 nuget 引用会导致本地构建发生冲突(您有 2 个来自不同来源的具有相同名称 (ValueTuple) 的结构),但 Microsoft 似乎做了一些聪明的事情,因此来自 Nuget 包的版本是如果 ValueTuple 包含在 mscorlib.dll 中,则忽略。见 cmetshere

这一切都让人感到非常讨厌,如果 MSBuild 找不到正确的目标包,我个人更喜欢它抛出一个硬错误,但它目前不是这样工作的。

【讨论】:

    【解决方案2】:

    感谢@Ross Gurbutt 为我指明了正确的方向。虽然通过谷歌搜索与引用 System.ValueTuple 相关的问题很容易找到,当它是 .NET 4.6.1 与 4.7 时,令人困惑的是它在我的本地成功编译而没有参考。尽管如此,我还是添加了对 nuget 包的引用,使用 MSBuild v15.0 的 Windows 2016 服务器能够成功构建 Web API 项目

    【讨论】:

      猜你喜欢
      • 2018-01-26
      • 2020-08-28
      • 1970-01-01
      • 2020-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-18
      相关资源
      最近更新 更多