仅构建一个 TargetFramework,同时定义多个 <TargetFrameworks> 以支持对其他 TargetFramework 的自定义构建

Only build one TargetFramework while defining multiple <TargetFrameworks> to support custom builds for other TargetFramework

想法很简单: 我想要一个项目文件,它可以构建多个目标框架,并根据所使用的框架引用不同的 DLL。

我 运行 遇到的问题是,当我 select 构建项目时,它将构建定义的所有框架 - 但引用的 .DLL 比其中一个更新目标框架(我需要用旧框架构建相同的项目)

我只想自动构建一个框架,然后手动构建其他框架。

<Project Sdk="Microsoft.NET.Sdk" InitialTargets="Test">
  <Target Name="Test">
    <Message Importance="high" Text="-- Building $(MSBuildProjectFile), TF=$(TargetFramework), Config=$(Configuration), Version=$(MyCustomVersion) --" />
  </Target>
  <PropertyGroup>
    <TargetFrameworks>net472;net48</TargetFrameworks>
    <MyCustomVersion Condition="'$(MyCustomVersion)' == ''">2022</MyCustomVersion>
    <OutputPath>bin$(Configuration)$(MyCustomVersion)\</OutputPath>
    <Configurations>Debug;Release</Configurations>
  </PropertyGroup>
  <PropertyGroup Condition="'$(MyCustomVersion)' == '2021' ">
    <PlatformTarget>x64</PlatformTarget>
    <DefineConstants>$(DefineConstants);V2021</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition="'$(MyCustomVersion)' == '2021' ">
    <PlatformTarget>x64</PlatformTarget>
    <DefineConstants>$(DefineConstants);V2021</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition="'$(MyCustomVersion)' == '2021' ">
    <PlatformTarget>x64</PlatformTarget>
    <DefineConstants>$(DefineConstants);V2021</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition="'$(MyCustomVersion)' == '2022' ">
    <PlatformTarget>x64</PlatformTarget>
    <DefineConstants>$(DefineConstants);V2022</DefineConstants>
  </PropertyGroup>
  <ItemGroup Condition="'$(MyCustomVersion)' == '2022' ">
    <Reference Include="Some48API">
      <HintPath>path\to\Some48API.dll</HintPath>
      <Private>False</Private>
    </Reference>
  </ItemGroup>
  <Target Name="BuildOthers" BeforeTargets="DispatchToInnerBuilds" Condition="'$(MyCustomVersion)' == '2022'">
    <Message Importance="high" Text="*** building 2019 ***" />
    <MSBuild Projects="$(MSBuildProjectFile)" Properties="Configuration=$(Configuration);TargetFramework=net472;MyCustomVersion=2019" />
    <Message Importance="high" Text="*** building 2020 ***" />
    <MSBuild Projects="$(MSBuildProjectFile)" Properties="Configuration=$(Configuration);TargetFramework=net472;MyCustomVersion=2020" />
    <Message Importance="high" Text="*** building 2021 ***" />
    <MSBuild Projects="$(MSBuildProjectFile)" Properties="Configuration=$(Configuration);TargetFramework=net48;MyCustomVersion=2021" />
  </Target>
</Project>

在上面的工程文件中,我有两个TargetFrameworks:net472和net48。 如果我用 <TargetFramework>net48</TargetFramework> 替换它(并将 BeforeTargets="DispatchToInnerBuilds" 修改为 BeforeTargets="PreBuildEvent"),我将得到一个编译错误

0>C:\Program Files\dotnet\sdk.0.202\Sdks\Microsoft.NET.Sdk\targets\Microsoft.PackageDependencyResolution.targets(267,5): Error NETSDK1005 : Assets file 'C:\Users\me\source\repos\Solution1\ClassLibrary1\obj\project.assets.json' doesn't have a target for 'net472'. Ensure that restore has run and that you have included 'net472' in the TargetFrameworks for your project.

所以我似乎需要同时提供两者,但我不想在没有我自己的自定义控制的情况下构建它们...

这个问题受到 TheBuildingCoder 的启发,特别是 RevitAPI dll 文件仅适用于 2021/2022 的 net48 - 所以我不想构建 net47,因为由于引用损坏而出现编译错误...

我意识到我试图做的事情没有多大意义... 我想阻止 VS 构建其他目标,只能手动构建其他目标...

因此,与其试图阻止自动构建其他目标,不如接受它。

更改后的项目文件如下所示(也更简化):

<Project Sdk="Microsoft.NET.Sdk" InitialTargets="Test">
  <Target Name="Test">
    <Message Importance="high" Text="-- Building $(MSBuildProjectFile), TF=$(TargetFramework), Config=$(Configuration), Version=$(MyCustomVersion) --" />
  </Target>
  <PropertyGroup>
    <TargetFrameworks>net472;net48</TargetFrameworks>
      <MyCustomVersion Condition="'$(MyCustomVersion)' == '' and '$(TargetFramework)' == 'net472'">2019</MyCustomVersion>
      <MyCustomVersion Condition="'$(MyCustomVersion)' == '' and '$(TargetFramework)' == 'net48'">2022</MyCustomVersion>
    <OutputPath>bin$(Configuration)$(MyCustomVersion)\</OutputPath>
    <Configurations>Debug;Release</Configurations>
    <IsPublishable>False</IsPublishable>
  </PropertyGroup>
  <PropertyGroup>
    <PlatformTarget>x64</PlatformTarget>
    <DefineConstants>$(DefineConstants);V$(MyCustomVersion)</DefineConstants>
  </PropertyGroup>
  <Target Name="BuildOthers" BeforeTargets="DispatchToInnerBuilds" Condition=" '$(MyCustomVersion)' == '' ">
    <MSBuild Projects="$(MSBuildProjectFile)" Properties="Configuration=$(Configuration);TargetFramework=net472;MyCustomVersion=2020" />
    <MSBuild Projects="$(MSBuildProjectFile)" Properties="Configuration=$(Configuration);TargetFramework=net48;MyCustomVersion=2021" />
  </Target>
</Project>

唯一的缺点是它没有按更好的顺序构建它们:

1>-- Building ClassLibrary1.csproj, TF=, Config=Debug, Version= --
1>-- Building ClassLibrary1.csproj, TF=net472, Config=Debug, Version=2020 --
1>ClassLibrary1 -> C:\Users\me\source\repos\Solution1\ClassLibrary1\bin\Debug20\net472\ClassLibrary1.dll
1>-- Building ClassLibrary1.csproj, TF=net48, Config=Debug, Version=2021 --
1>ClassLibrary1 -> C:\Users\me\source\repos\Solution1\ClassLibrary1\bin\Debug21\net48\ClassLibrary1.dll
1>-- Building ClassLibrary1.csproj, TF=net472, Config=Debug, Version=2019 --
1>ClassLibrary1 -> C:\Users\me\source\repos\Solution1\ClassLibrary1\bin\Debug19\net472\ClassLibrary1.dll
1>-- Building ClassLibrary1.csproj, TF=net48, Config=Debug, Version=2022 --
1>ClassLibrary1 -> C:\Users\me\source\repos\Solution1\ClassLibrary1\bin\Debug22\net48\ClassLibrary1.dll

2020,2021,2019,2022 但这是一个小的不便,可能可以通过一些改组来解决