PackageReference 条件被忽略

PackageReference condition is ignored

在我的 VS 2017 项目中,我引用了 docfx.console 包,我希望它仅在满足特定条件时使用。但是这个包被用于所有构建。

这是我项目的一部分。我希望在配置为 Installer/AnyCPU 并且 VS 正在构建 net40 风格时使用 docfx.console。

<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>net40;netstandard1.3;netstandard2.0</TargetFrameworks>
    <!-- ... -->
    <Configurations>Debug;Release;Installer</Configurations>
  </PropertyGroup>

  <ItemGroup Condition=" '$(TargetFramework)'=='net40' ">
    <!-- ... -->
    <PackageReference Include="docfx.console" Version="2.30.0" Condition="'$(Configuration)|$(Platform)'=='Installer|AnyCPU'" />
  </ItemGroup>

    <!-- ... -->
</Project>

有没有办法在仅适用于 net40 的安装程序构建中使用 docfx.console?

PackageReference condition is ignored

这是关于新样式 csproj PackageReference 的 known issue,用于处理 nuget 包中的 content/Tools 文件。

在包 docfx.console 中,看起来 docfx.console 有“content”、“build”和“tools”,但没有 .NET 代码其中,只是随机文件:

在这种情况下,当我们安装这个nuget包时,nuget并没有做任何事情。所以它似乎被用于所有构建。那是因为:

NuGet packages that work with Packages.config, don't always work in transitive NuGet environments (projects using Project.json or PackageReferences). Packages that work in transitive NuGet environments must use "contentFiles" instead of "content" -- you can have both, if a package would like to work in both environments. Also, install.ps1/uninstall.ps1 doesn't execute in transitive NuGet environments -- however, init.ps1 will work in both Packages.config and transitive environments.

暂时还没有完美的解决方案,所以the issue 4837还未解决

要解决此问题,需要更改 NuGet docfx.console 包以使用 contentFiles 并定义目标,并且通常会使用 $(MSBuildThisFileDirectory)..\tools\MyTool.exe 引用工具。如果将此 PackageName.targets 文件放入构建目录,它将自动包含在引用 NuGet 包的项目中。

希望这对您有所帮助。

总而言之,即使条件 "false",包也会被导入。

<Project Sdk="Microsoft.NET.Sdk">    
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFrameworks>netcoreapp3.0;netcoreapp2.2;net472</TargetFrameworks>
    <Platforms>x64;x86</Platforms>
  </PropertyGroup>
  <ItemGroup Condition="false">
      <PackageReference Include="MyPackage" Version="1.0.0" />
  </ItemGroup>
</Project>

我们发现我们可以通过将包引用放在不同的文件中并使文件的导入有条件地解决这个问题。

单独的文件:packagerefs.targets

<Project Sdk="Microsoft.NET.Sdk">    
  <ItemGroup>
      <PackageReference Include="MyPackage" Version="1.0.0" />
  </ItemGroup>
</Project>

项目文件:

<Project Sdk="Microsoft.NET.Sdk">    
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFrameworks>netcoreapp3.0;netcoreapp2.2;net472</TargetFrameworks>
    <Platforms>x64;x86</Platforms>
  </PropertyGroup>
  <Import Project="packagerefs.targets" Condition="false" />
</Project>

甚至我一直在寻找基于条件的引用 nuget 包(仅当在 DefineConstants 中设置预期常量时才加载)。尽管@Luke Schoen Solution 对我有用,但我可以在没有外部目标文件的情况下使其工作。

解决方案是使用 Choose > When

来包含您的 PackageReference

确保在具有 DefineConstants 的 PropertyGroup 之后有此块。

<Choose>
<When Condition="$(DefineConstants.Contains('My_CONST'))">
  <ItemGroup>
  <PackageReference Include="MyPackage">
    <Version>1.0.6</Version>
  </PackageReference>
  </ItemGroup>
</When>  </Choose>

在我的情况下,我也遇到了同样的问题 - 但根本原因是在执行 nuget 包构建时未定义某些 msbuild 属性 - 特别是 $(SolutionName) 未定义。 Condition 仍然得到评估,只是由于某种原因它返回 true 。 (您可以通过输入 Condition="false" 来测试 - 它会被省略)。

我的解决方案是检查是否定义了 属性,例如:

  <ItemGroup Condition="'$(SolutionName)' != '' and $(SolutionName.Contains('SolutionCustomTag'))">
    <Reference Include="...">

第一个语句 '$(SolutionName)' != '' and - 测试 属性 是否已定义。