无法命令行构建混合解决方案(.NET Framework与.NET标准)

mck*_*dev 6 .net msbuild teamcity .net-standard

简短版本:我有一个VS2017解决方案,包含2个.NET Standard 2.0项目,一个.NET Framework 4.6.2类库和.NET Framework 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 - 面向.NET Framework 4.6.2的MVC 5.0 ASP.NET Web应用程序项目.这是一个最初在Visual Studio 2013中创建的MVC Web应用程序,并且已经多次升级以跟上.NET Framework升级.

ModelsLibrary - .NET Standard 2.0,同时针对Standard和4.6.2*.除了在整个解决方案中使用的普通C对象外,只包含其他内容.

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

ServiceLibrary - .NET Framework 4.6.2类库项目.执行WebApp的CRUD操作.从数据库中提取,插入或更新的所有对象都是ModelsLibrary项目中的POCO.无法更新到.NET Standard,因为我们在整个项目中都非常依赖linq to SQL,并且在.NET Standard中没有实现linq to SQL.

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>
Run Code Online (Sandbox Code Playgroud)

该解决方案具有以下参考:

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\
Run Code Online (Sandbox Code Playgroud)

为什么在命令行中出现此错误但在Visual Studio 2017中没有显示任何问题?有什么不同的做法?好吧,让我们尝试在.NET Framework项目上使用相当多的NuGet包进行恢复:

c:\MySolutionName>dotnet restore ServiceLibrary
  Nothing to do. None of the projects specified contain packages to restore.
Run Code Online (Sandbox Code Playgroud)

但是当我使用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使用哪些命令,更重要的是哪些版本的实用程序来构建这样的解决方案?

mck*_*dev 5

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

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

删除packages目录下的所有文件:

del %system.teamcity.build.workingDir%\packages /F /S /Q
rd /s /q %system.teamcity.build.workingDir%\packages
Run Code Online (Sandbox Code Playgroud)

运行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
Run Code Online (Sandbox Code Playgroud)

构建解决方案:

"C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\bin\MSBuild.exe" %system.teamcity.build.workingDir%\MyWebProject.sln /p:Configuration=MyConfiguration /p:DeployOnBuild=true /p:PublishProfile=MyPublishProfile
Run Code Online (Sandbox Code Playgroud)