含.NET Framework项目的解决方案中,MSBuild无法找到.NET Standard项目的包
解决.NET Standard项目添加NuGet包后MSBuild命令行构建失败的问题
问题背景
你遇到的情况很典型:混合了.NET Standard 2.0和.NET Framework 4.7.2的解决方案,在Visual Studio里构建一切正常,但用MSBuild.exe命令行构建时,却找不到.NET Standard项目中添加的Newtonsoft包引用。这是因为VS和命令行MSBuild在处理跨项目类型的NuGet依赖传递时,行为存在差异。
核心原因分析
- NuGet管理方式不匹配:你的.NET Standard项目默认使用
PackageReference管理NuGet包(所以包会存在于用户目录的.nuget/packages而非解决方案的./packages),但.NET Framework项目(proj C、D)大概率还是用旧的packages.config方式。这种情况下,packages.config的项目无法自动接收来自.NET Standard项目的NuGet依赖传递——VS内部会做额外处理来兼容,但命令行MSBuild不会。 - Restore命令的局限性:你用的
nuget.exe restore对混合PackageReference和packages.config的解决方案支持不够完善,无法正确解析.NET Standard项目的依赖并同步到.NET Framework项目中。
解决方案
下面按优先级推荐几种解决方法:
1. 将.NET Framework项目迁移到PackageReference(推荐)
这是最彻底的解决方式,能从根源上消除依赖传递的问题:
- 在Visual Studio中右键点击proj C或D,选择管理NuGet程序包,点击右上角的设置图标,选择迁移到PackageReference,按照向导完成迁移。
- 迁移后,这些项目会自动识别并引用来自.NET Standard项目的NuGet依赖,无需手动添加。
2. 手动给.NET Framework项目添加Newtonsoft包引用
如果暂时不想迁移NuGet管理方式,可以直接给proj C和D添加Newtonsoft包的引用:
- 用
nuget.exe install Newtonsoft.Json -Version [你的版本号] -OutputDirectory ./packages下载包到解决方案的./packages目录。 - 在proj C和D的
.csproj文件中添加对应的引用,或者通过VS的NuGet包管理器安装。
3. 替换Restore命令为dotnet restore
dotnet restore对混合项目类型的支持更好,能同时处理PackageReference和packages.config的依赖:
修改你的CI脚本:
dotnet restore $SOLUTION_FILE "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe" '/p:Configuration=release' $SOLUTION_FILE
注意:要指定VS 2017对应的MSBuild路径,避免使用系统默认的旧版本MSBuild。
4. 确保MSBuild使用VS的环境变量
在命令行中先加载VS的开发环境变量,再执行构建:
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat" nuget.exe restore $SOLUTION_FILE MSBuild.exe '/p:Configuration=release' $SOLUTION_FILE
这样MSBuild会使用VS的完整构建环境,和VS内部的构建行为保持一致。
额外说明
你不需要把.NET Standard项目打包成NuGet包——同一解决方案中的项目引用完全可行,问题出在跨项目类型的NuGet依赖传递处理上。
内容的提问来源于stack exchange,提问作者Alex McLean
相关产品推荐
相关产品推荐

