繁体   English   中英

使用 MSBuild 时加载的 nuget 包与使用 Visual Studio 构建时加载的不同

[英]Different nuget-packages loaded when using MSBuild than building using Visual Studio

我还在微软论坛上发布了这个问题: https://learn.microsoft.com/en-us/answers/questions/249621/different-nuget-packages-are-used-when-compiling-u.html

考虑以下 .csproj 文件:

 <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
   <PropertyGroup>
     <OutputType>WinExe</OutputType>
     <TargetFrameworks>netcoreapp3.1;net5.0-windows</TargetFrameworks>
     <UseWPF>true</UseWPF>
   </PropertyGroup>
    
     <ItemGroup>
         <PackageReference Include="Newtonsoft.Json" Version="12.0.3" Condition="'$(TargetFramework)' == 'net5.0-windows'"/>
         <PackageReference Include="Newtonsoft.Json" Version="11.0.1" />
     </ItemGroup>
 </Project>

本项目除了创建项目时visual studio生成的文件外,没有其他文件。 生成的文件(.csproj 文件除外)不会以任何方式更改。

在此处输入图像描述

正如您在图中所见,visual studio 将 - 对于这两个项目 - 引用 11.0.1 版本,并且还使用 11.0.1 版本构建可执行文件。

将命令行与 MSBuild 一起使用时

<msbuildpath> <projectpath> /restore

.net5.0 目标将使用 12.0.3 版本生成可执行文件,其他目标将使用 11.0.1 版本生成可执行文件

从命令行使用 nuget.exe /restore 时,它还会生成资产文件,以将 12.0.3 用于 .net5.0,将 11.0.1 用于其他目标。

为什么使用 visual studio 和 nuget/msbuild 的包有区别? 这是预期的行为还是错误?

*作为旁注,当使用 choose/when 标签时问题会自行解决

<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
   <PropertyGroup>
     <OutputType>WinExe</OutputType>
     <TargetFrameworks>netcoreapp3.1;net5.0-windows</TargetFrameworks>
     <UseWPF>true</UseWPF>
   </PropertyGroup>
    
     <Choose>
         <When Condition="'$(TargetFramework)' == 'net5.0-windows'">
             <ItemGroup>
                 <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
             </ItemGroup>
         </When>
         <Otherwise>
             <ItemGroup>
                 <PackageReference Include="Newtonsoft.Json" Version="11.0.1" />
             </ItemGroup>
         </Otherwise>
     </Choose>
 </Project>
  • 无论哪种构建方法生成正确的 output,我都希望 MSBuild 和 VS 生成相同的 output。还是我错了?
  • 为什么使用 visual studio 和 nuget/msbuild 的包有区别?
  • 这是预期的行为还是错误?

请先查看更新。

VS IDE Restore 和nuget restore , msbuild -t:Restore命令行有很大区别。

这不是我之前在 VS IDE 还原和命令行还原之间遇到的第一个问题。 看到我几天前提出的这个问题

主要问题是VS IDE Restore问题有点多,需要修复。

我已将此问题报告给团队。 见一二 如果我没有详细描述问题,您可以关注问题、投票并添加任何评论。

由于这个过程可能需要很长时间,现在,你必须使用我的解决方法,放弃 VS IDE 还原并改为使用还原命令:

1)输入Tools --> Options --> Nuget Package Manager并取消选中这两个选项,以防 vs ide 后端继续使用 ide restore 来执行错误行为。

在此处输入图像描述

2)右击Project Properties --> Build Event --> Pre-build event command line下添加do.net restore

在此处输入图像描述

3)关闭VS,删除项目的binobj文件夹,然后在VS上重启你的项目,点击Rebuild得到你想要的。

更新 1

我觉得这个问题很奇怪。 我认为问题在于:

 <PackageReference Include="Newtonsoft.Json" Version="11.0.1" />

是最后一项并且没有条件。 它也适用于net5.0-windows11.0.1版本,因为它在项目的最后一行。

所以你应该改用这个:

<ItemGroup>
        <PackageReference Include="Newtonsoft.Json" Version="11.0.1" />
        <PackageReference Include="Newtonsoft.Json" Version="12.0.3" Condition="'$(TargetFramework)' == 'net5.0-windows'" />
</ItemGroup>

最后提出条件。

要么

<ItemGroup>
        <PackageReference Include="Newtonsoft.Json" Version="11.0.1" Condition="'$(TargetFramework)' == 'netcoreapp3.1'"/>
        <PackageReference Include="Newtonsoft.Json" Version="12.0.3" Condition="'$(TargetFramework)' == 'net5.0-windows'" />
</ItemGroup>

每个item一个条件(比如choose, when ),避免targetframework.net5.0包含nuget package两次,这样就不会导致复杂的情况。

但是choose, whenif, else时,只会根据条件执行一个项目,但您提供的第一个代码不相同,这是两个PackageReference包含项目,而MSBuild将执行这两个项目,当它执行第二行时,它适用于net5.0-windowsnetcoreapp3.1 ,因此net5.0-windows将包含11.0.1版本。 那是正常的。

重要分析

问题是VS IDE Restore只会显示最后一个PackageReference包含项的版本并使用该版本。

在你身边,这些是你使用的:

<ItemGroup>
         <PackageReference Include="Newtonsoft.Json" Version="12.0.3" Condition="'$(TargetFramework)' == 'net5.0-windows'"/>
         <PackageReference Include="Newtonsoft.Json" Version="11.0.1" />
</ItemGroup>

由于11.0.1是最后一个包含,因此它始终显示11.0.1 但是Restore Command line不同,它只显示第一个 PackageReference include 节点。 在您这边,如果您使用do.net Restore Command line ,它将使用第一个节点12.0.3 它忽略了第二行,尽管它确实如此。

这是我的环境:

在这种情况下net5.0-windows有两个include,依次是11.0.1netcoreapp3.1 12.0.3 11.0.1

在此处输入图像描述

我在 msbuild 下面使用了do.net restore 。但是它使用了第一个包含 nuget 的版本。 net5.0-windows使用11.0.1netcoreapp3.1使用11.0.1

在此处输入图像描述

当我在下面使用VS IDE Restore时,它使用了最后一个包含PackageReference nuget 版本。

net5.0-windows使用12.0.3版本, netcoreapp3.1使用11.0.1版本。

所以我很好奇为什么这种行为在VS IDE Restoredo.net Restore Command之间是不同的。

因此,显然 Visual Studio 不会像 MSBuild 那样处理 MSBuild 脚本中的条件,因此会产生其他结果。 我找不到有关他们是否会解决此问题的任何信息。 可能不是因为根据这篇文章,自 VS2010 以来这已经发生了。 https://medium.com/@corradocavalli/msbuild-conditions-and-visual-studio-6c5c9347cccf

正如@Kit 在 OP 的评论中所说,使用 Choose/When 将解决这个问题。 无论如何,我会将其标记为已回答,直到出现更好的答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM