无法通过命令行构建混合解决方案(.NET Framework 与 .NET Standard)

Unable to Command-Line Build a Mixed Solution (.NET Framework with .NET Standard)

简短版本:我有一个 VS2017 解决方案,其中包含 2 个 .NET Standard 2.0 项目、一个 .NET Framework 4.6.2 class 库和 .NET框架 4.6.2 MVC WebApp。恢复所有 nuget 包然后在解决方案中构建所有项目的正确命令行构建实用程序是什么?

长版本: 我已经将针对 .NET Framework 4.5 和 Visual Studio Pro 2015 的解决方案迁移到 Visual Studio Pro 2017,其中一些项目针对 . NET Framework 4.6.2 和一些目标 .NET Standard 2.0。根据https://github.com/dotnet/standard/blob/master/docs/versions.md,这个Framework/Standard的特定版本组合应该是兼容的。

这是我今天的解决方案:

WebApp - MVC 5.0 ASP.NET 面向 .NET Framework 4.6.2 的 Web 应用程序项目。这是一个 MVC 网络应用程序,最初创建于 Visual Studio 2013 年,并已升级多次以跟上 .NET Framework 的升级。

ModelsLibrary - .NET Standard 2.0,同时针对 Standard 和 4.6.2*。仅包含在整个解决方案中使用的普通旧 C 对象。

LogicLibrary - .NET Standard 2.0,同时针对 Standard 和 4.6.2*。包含对我们的 POCO 进行更改的业务逻辑and/or 使用来自我们 POCO 的数据调用第三方服务。

ServiceLibrary - .NET Framework 4.6.2 class 库项目。为 WebApp 执行 CRUD 操作。从数据库中获取、插入或更新的所有对象都是来自 ModelsLibrary 项目的 POCO。无法更新到 .NET Standard,因为我们在整个项目中严重依赖 linq to SQL,而 linq to SQL 未在 .NET Standard 中实现。

TestsProject - 使用 Microsoft.VisualStudio.QualityTools.UnitTestFramework 的 .NET Framework 4.6.2 单元测试项目。对我们在整个解决方案中执行的少量关键逻辑操作执行基本单元测试。这个项目,如果是问题,可以去掉,及时换成新的测试项目。

*ModelsLibrary 和 LogicLibrary 项目的 CSProj 文件包含以下行:

<TargetFrameworks>netstandard2.0;net462</TargetFrameworks>
<TargetFrameworkIdentifier Condition="'$(_ShortFrameworkIdentifier)'=='net'">.NETFramework</TargetFrameworkIdentifier>
<TargetFrameworkIdentifier Condition="'$(_ShortFrameworkIdentifier)'=='netstandard'">.NETStandard</TargetFrameworkIdentifier>

解决方案参考如下:

WebApp 引用 LogicLibrary、ModelsLibrary、ServiceLibrary

LogicLibrary 对 ModelsLibrary

有项目依赖

ModelsLibrary 没有项目依赖性

ServiceLibrary 引用 ModelsLibrary

TestsProject 引用 WebApp、ServiceLibrary、ModelsLibrary

整个解决方案可以使用 Visual Studio 2017 构建、运行和发布,没有任何构建错误或问题。但是,我们的持续集成和持续部署系统是完全不能运行的。为了简化这个问题,我只询问如何执行我的解决方案的命令行构建。一旦知道,我就可以调整我们的 CI/CD 解决方案以利用给定的命令。进行构建的服务器安装了 VS2017Pro,安装了 .NET Framework 4.7.1 目标包,以及所有适当的更新。

这是我认为在构建过程中应该发生的事情的一般化伪命令想法: 1. 从源代码管理中提取解决方案的最新代码 2.恢复所有nuget包 3. 构建解决方案中的所有项目。我的假设是这样的顺序:ModelsLibrary、LogicLibrary、ServiceLibrary、WebApp。

但是,当我尝试使用命令行工具进行构建时遇到了很多错误。马上开始:

dotnet restore ModelsLibrary
Errors in c:\MySolutionName\ModelsLibrary\ModelsLibrary.csproj
    Package Microsoft.AspNet.WebUtilities 1.0.0-rc1-final is not compatible with netstandard2.0 (.NETStandard,Version=v2.0). Package Microsoft.AspNet.WebUtilities 1.0.0-rc1-final supports:
      - dotnet5.4 (.NETPlatform,Version=v5.4)
      - net451 (.NETFramework,Version=v4.5.1)
    One or more packages are incompatible with .NETStandard,Version=v2.0.

NuGet Config files used:
    C:\Users\MyUserName\AppData\Roaming\NuGet\NuGet.Config
    C:\Program Files (x86)\NuGet\Config\Microsoft.VisualStudio.Offline.config

Feeds used:
    https://api.nuget.org/v3/index.json
    C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\

为什么在命令行上会出现此错误,但在 Visual Studio 2017 中却没有显示任何问题?有什么不同之处?好的,让我们尝试还原使用大量 NuGet 包的 .NET Framework 项目:

c:\MySolutionName>dotnet restore ServiceLibrary
  Nothing to do. None of the projects specified contain packages to restore.

但是当我使用当前推荐的 NuGet 4.4.1 版本时,此项目的 nuget 包恢复没有问题,但 NuGet 再次显示 ModelsLibrary 的上述错误。

这不是唯一的问题,只是我在尝试为解决方案执行命令行构建时遇到的众多问题之一。为了解决这些包问题,我恢复了使用 VisualStudio 本身的包,然后尝试使用 "dotnet build" 和 msbuild(来自 VisualStudio 2017 目录)进行构建,但两个命令都无法成功构建解决方案。在特定项目上使用 "dotnet build" 也不会起作用。错误太多,无法在此一一列举。

所以问题归结为: 为什么此解决方案在 Visual Studio 2017 年内构建良好,但不能通过使用 dotnet/msbuild 的命令行构建?在允许成功构建的 VS 中做了哪些不同的事情? Visual Studio 2017 Pro 使用什么命令,更重要的是,什么版本的实用程序来构建这样的解决方案?

简短版本:Lex Li 的建议是正确的。从头开始成功了,这只乌鸦确实味道很好。

长版本:我在 Visual Studio 2017 年创建了一个 b运行d 新解决方案,并使用 .NET Framework 4.7.1 和 .NET Standard 2.0 创建了每个项目的新版本。然后,我从原始项目中复制了所有文件,并花了很长时间解决所有 nuget 和依赖性问题。一旦我可以让项目在 visual studio 中再次构建,在命令行中构建就相当简单了。我 运行 遇到的另一个故障是一个问题 因为我的实际用例是在团队城市中,所以这里是我可以用来构建解决方案的命令行步骤:

删除包目录中的所有文件:

del %system.teamcity.build.workingDir%\packages /F /S /Q
rd /s /q %system.teamcity.build.workingDir%\packages

运行 nuget 恢复:

C:\TeamCity\buildAgent\tools\NuGet.CommandLine.4.6.1\tools\NuGet.exe restore %system.teamcity.build.workingDir%\MyWebProject\packages.config -PackagesDirectory %system.teamcity.build.workingDir%\packages -NonInteractive
dotnet restore %system.teamcity.build.workingDir%\MyModelsProject
dotnet restore %system.teamcity.build.workingDir%\MyLogicProject

构建解决方案:

"C:\Program Files (x86)\Microsoft Visual Studio17\Professional\MSBuild.0\bin\MSBuild.exe" %system.teamcity.build.workingDir%\MyWebProject.sln /p:Configuration=MyConfiguration /p:DeployOnBuild=true /p:PublishProfile=MyPublishProfile