在同一个 NuGet 包中为 .Net 4.7.2 和 .Net 6.0 构建?

Build for .Net 4.7.2 and .Net 6.0 in same NuGet package?

我能够为 .NET Framework 4.7.2 项目创建 NuGet 包。

# .NET Desktop
# Build and run tests for .NET Desktop or Windows classic desktop solutions.
# Add steps that publish symbols, save build artifacts, and more:
# https://docs.microsoft.com/azure/devops/pipelines/apps/windows/dot-net

name: $(Date:yy).$(Date:MM).$(Rev:r)

trigger: 
- master

pool:
  vmImage: 'windows-latest'

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'

steps:
- task: NuGetToolInstaller@1

- task: NuGetCommand@2
  displayName: NuGet restore
  inputs:
    restoreSolution: '$(solution)'

- task: VSBuild@1
  inputs:
    solution: '$(solution)'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'

- task: NuGetCommand@2
  displayName: 'NuGet pack'
  inputs:
    command: 'pack'
    packagesToPack: '**/*.csproj'
    versioningScheme: 'byBuildNumber'

- task: CopyFiles@2
  inputs:
    sourceFolder: '$(Build.SourcesDirectory)'
    contents: '**/$(BuildConfiguration)/**'
    targetFolder: '$(Build.ArtifactStagingDirectory)'

- task: NuGetCommand@2
  displayName: 'NuGet push'
  inputs:
    command: 'push'
    packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.nupkg;!$(Build.ArtifactStagingDirectory)/**/*.symbols.nupkg'
    nuGetFeedType: 'internal'
    allowPackageConflicts: true

- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)'
    ArtifactName: 'drop'
    publishLocation: 'Container'

但我想为 .NET 6.0 构建一个版本。我感到失落。我很抱歉这样问,但我该怎么办。多重构建定义?多项任务?

要使用 multi-targeting 支持,您需要始终使用新的构建工具链。也就是说,您需要使用 .NET SDK 而不是旧的 MSBuild/NuGet.exe 工具来构建和打包。

因此,首先您需要使用 new .csproj format 来构建您的项目文件。要同时定位 net472net6.0,请使用 <TargetFrameworks> 元素(相对于 <TargetFramework> 元素)。您还应该为不想打包到 .nupkg 文件中的任何项目设置 <IsPackable>false</IsPackable>,因为 multi-targeting 是通过在 解决方案级别 打包完成的。

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>net6.0;net472</TargetFrameworks>
    <IsPackable>true</IsPackable>
  </PropertyGroup>

  <ItemGroup>
  <!-- This is to allow the .NET Framework references to be machine-indepenedent so builds can happen without installing prerequisites -->
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.2" PrivateAssets="All" />
  </ItemGroup>
</Project>

Microsoft.NETFramework.ReferenceAssemblies 添加为私有资产可确保您的 .NET Framework 4.7.2 构建甚至可以在 Linux 和 macOS 上运行。您只需要构建机器上的 .NET 6+ SDK

您需要使用dotnet build to do the building and dotnet pack来打包。这两个都应该在解决方案文件上执行。

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'
  sdkVersion: '6.0.202'
  nugetArtifactName: 'nuget'

steps:
# Install .NET SDK
- task: UseDotNet@2
  displayName: 'Use .NET SDK $(sdkVersion)'
  inputs:
    packageType: 'sdk'
    version: '$(sdkVersion)'

# Restore and build the solution (if not supplying --no-restore, it is automatic)
- task: DotNetCoreCLI@2
  displayName: 'dotnet build $(solution)'
  inputs:
    command: custom
    projects: '$(solution)'
    custom: build
    arguments: '--configuration $(buildConfiguration) --verbosity normal /p:Platform="$(buildPlatform)"

# Pack the solution with the --no-build argument.
# You may need to pass additional parameters here, such as /p:PackageVersion="$(PackageVersion)".
- task: DotNetCoreCLI@2
  displayName: 'dotnet pack'
  inputs:
    command: custom
    projects: '$(solution)'
    custom: pack
    arguments: '--configuration $(buildConfiguration) --output "$(Build.ArtifactStagingDirectory)/$(nugetArtifactName)" --no-build --verbosity normal'

# Publish the NuGet artifacts to ensure they can be inspected if any step after this fails
- task: PublishBuildArtifacts@1
  displayName: 'Publish Artifact: $(nugetArtifactName)'
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)/$(nugetArtifactName)'
    ArtifactName: '$(nugetArtifactName)'
  condition: succeededOrFailed()

# Push the NuGet files to a temporary feed (optional)
- task: NuGetCommand@2
  displayName: 'NuGet push'
  inputs:
    command: 'push'
    packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.nupkg;!$(Build.ArtifactStagingDirectory)/**/*.symbols.nupkg'
    nuGetFeedType: 'internal'
    allowPackageConflicts: true

Technically, dotnet restore, dotnet build, and dotnet pack are 3 separate commands. However, for this scenario, the only one you actually need to execute is dotnet pack. By default it will run the other two if the --no-build parameter is not supplied. But, to make the build more manageable, it is sometimes advantageous to use them as separate commands to keep it more clear what the MSBuild parameters are for.