You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多目标项目中GenerateNuspec前调用NuGet的MSBuild任务报错解决

问题:多目标项目外部构建无法使用NuGet包中的MSBuild任务

我在多目标项目的外部构建中无法使用引用NuGet包提供的MSBuild任务,但该任务在内部构建(DispatchToInnerBuilds)中运行正常。我需要在GenerateNuspec之前(DispatchToInnerBuilds之后)设置属性来控制包版本,但执行时总是报错:error MSB4036: The "JsonPeek" task was not found.,单目标项目不存在此问题。

简化演示项目

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
    <LangVersion>latest</LangVersion>
    <IsPackable>true</IsPackable>
  </PropertyGroup>

  <PropertyGroup>
    <Title>Test project.</Title>
    <Description></Description>
    <PackageIcon>Git2SemVer_icon_32x32.png</PackageIcon>
    <ApplicationIcon>Git2SemVer_icon_64x64.ico</ApplicationIcon>
    <PackageReadmeFile>NuGet_description.md</PackageReadmeFile>
    <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
    <SuppressDependenciesWhenPacking>false</SuppressDependenciesWhenPacking>
    <GenerateDependencyFile>true</GenerateDependencyFile>
    <UpdateVersionProperties>true</UpdateVersionProperties>
    <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
    <PackageOutputPath>./nupkg</PackageOutputPath>
  </PropertyGroup>

  <ItemGroup>
    <None Include="..\Documentation\Images\Git2SemVer_icon_32x32.png" Link="Git2SemVer_icon_32x32.png" Pack="True" PackagePath="\" />
    <Content Include="Git2SemVer_icon_64x64.ico" Pack="False" />
    <None Include="NuGet_description.md" Pack="True" PackagePath="\" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="JsonPeek" Version="1.2.0" />
    <PackageReference Include="Semver" Version="[2.3.0]" />
    <PackageReference Include="Injectio" Version="3.3.0" />
    <PackageReference Include="Spectre.Console" Version="0.49.1" />
    <PackageReference Include="System.Text.Json" Version="8.0.5" />
  </ItemGroup>

   <Target Name="OuterPreBuild" BeforeTargets="DispatchToInnerBuilds">
    <Message Importance="high" Text="========================================Outer before build" />
  </Target>

  <Target Name="OuterPreBuild" AfterTargets="DispatchToInnerBuilds">
    <Message Importance="high" Text="========================================Outer after build: $(PackageVersion) | $(Git2SemVer_SharedVersioningJsonFile)" />

<!-- 注:Git2SemVer_SharedVersioningJsonFile 是在未提供的 Directory.Build.props 文件中定义的有效属性 -->

    <!-- ReSharper disable once UnknownTask -->
    <JsonPeek ContentPath="$(Git2SemVer_SharedVersioningJsonFile)" Query="$.Git2SemVerVersionInfo">
      <Output TaskParameter="Result" ItemName="Git2SemVerVersionInfo" />
    </JsonPeek>

    <PropertyGroup>
      <Version>@(Git2SemVerVersionInfo -> '%(Version)')</Version>
      <VersionPrefix>@(Git2SemVerVersionInfo -> '%(VersionPrefix)')</VersionPrefix>
      <VersionSuffix>@(Git2SemVerVersionInfo -> '%(VersionSuffix)')</VersionSuffix>
      <PackageVersion>@(Git2SemVerVersionInfo -> '%(PackageVersion)')</PackageVersion>
      <InformationalVersion>@(Git2SemVerVersionInfo -> '%(InformationalVersion)')</InformationalVersion>
      <AssemblyVersion>@(Git2SemVerVersionInfo -> '%(AssemblyVersion)')</AssemblyVersion>
      <FileVersion>@(Git2SemVerVersionInfo -> '%(FileVersion)')</FileVersion>
    </PropertyGroup>

  </Target>

</Project>

简化错误输出

1>Target DispatchToInnerBuilds:
1>  Target FindReferenceAssembliesForReferences:
1>    Target GenerateTargetFrameworkMonikerAttribute:
1>      Skipping target "GenerateTargetFrameworkMonikerAttribute" because all output files are up-to-date with respect to the input files.

           :   省略大量输出行

1>  Done building project "Common.csproj".
1>Target OuterPreBuild:
1>  ========================================Outer after build: 1.0.0 | C:\Sources\NoeticTools\Common\SolutionVersioningProject/.git2semver/Git2SemVer.VersionInfo.g.json
1>  C:\Sources\NoeticTools\Common\Common\Common.csproj(62,5): error MSB4036: The "JsonPeek" task was not found. Check the following: 1.) The name of the task in the project file is the same as the name of the task class. 2.) The task class is "public" and implements the Microsoft.Build.Framework.ITask interface. 3.) The task is correctly declared with <UsingTask> in the project file, or in the *.tasks files located in the "C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\amd64" directory.
1>Done building target "OuterPreBuild" in project "Common.csproj" -- FAILED.
1>
1>Done building project "Common.csproj" -- FAILED.
1>
1>Build FAILED.

我可以在内部构建中正常使用JsonPeek,但外部构建不行。我需要在外部构建阶段执行它来设置包版本,而二进制文件已经用正确版本构建完成。想知道是操作有误还是根本无法实现?


解决方案

要在多目标项目的外部构建阶段(比如用于GenerateNuspec)使用NuGet包中的MSBuild任务,该包必须在buildmultitargeting目录下包含对应的props和targets文件。

我将props和targets文件同时放在buildmultitargeting和build目录中,通过导入tasks目录里的实际文件来实现(参考其他项目的做法),文件内容如下:

<?xml version="1.0" encoding="utf-8"?>

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildThisFileDirectory)..\tasks\$(MSBuildThisFile)" />
</Project>

最终的NuGet包目录结构:

  • build
    • JsonPeek.props
    • JsonPeek.targets
  • buildmultitargeting
    • JsonPeek.props
    • JsonPeek.targets
  • tasks
    • JsonPeek.props
    • JsonPeek.targets

内容的提问来源于stack exchange,提问作者Rob Smyth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 13:37:06