dotnet / samples

Sample code referenced by the .NET documentation
https://docs.microsoft.com/samples/browse
Creative Commons Attribution 4.0 International
3.39k stars 5.08k forks source link

PackageReference in msbuild\custom-task-code-generation\AppSettingStronglyTyped is not working #6610

Open Tripletri opened 9 months ago

Tripletri commented 9 months ago

Issue description

The approaches used in the AppSettingStronglyTyped example no longer work for using NuGet packages in projects with MSBuild Tasks. When creating a package containing MSBuild Tasks, you cannot use NuGet packages as in a regular ClassLibrary project; NuGet packages, or more precisely the dlls supplied with them, must be bundled with the final package.

To achieve these goals, AppSettingStronglyTyped uses CopyProjectReferencesToPackage Target: https://github.com/dotnet/samples/blob/d51488ecd50cf8dc774bdb0e0e6e2044bbe5ba5e/msbuild/custom-task-code-generation/AppSettingStronglyTyped/AppSettingStronglyTyped/AppSettingStronglyTyped.csproj#L41-L48

However, Microsoft.Extensions.DependencyInjection.dll is not included in the final package. I expect that after running dotnet package .nupkg will have tasks\netstandard2.0\Microsoft.Extensions.DependencyInjection.dll, but it doesn't. Which leads to an error loading the library during the build:

System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.

Steps to reproduce

Sample to reproduce https://github.com/Tripletri/samples/pull/1, integration tests is falling on this commit. image

Other thoughts

Since CopyProjectReferencesToPackage use ReferenceCopyLocalPathsReferenceCopyLocalPaths and @(ReferenceCopyLocalPaths) is always empty, this may relate to https://github.com/dotnet/sdk/issues/3662.

As a workaround, I simply commit the external DLLs, reference them with <Reference> and manually copy them at build time.

First of all, I'm interested in how to achieve this use of PackageReference in projects with MSBuild Tasks, especially with multi-targeting, since manually managing dependencies for all target frameworks is a headache.

Thanks in advice

Target framework

dotnet --info output ```console .NET SDK: Version: 8.0.101 Commit: 6eceda187b Workload version: 8.0.100-manifests.0f7d8591 Runtime Environment: OS Name: Windows OS Version: 10.0.19045 OS Platform: Windows RID: win-x64 Base Path: C:\Program Files\dotnet\sdk\8.0.101\ .NET workloads installed: Workload version: 8.0.100-manifests.0f7d8591 There are no installed workloads to display. Host: Version: 8.0.1 Architecture: x64 Commit: bf5e279d92 .NET SDKs installed: 2.1.202 [C:\Program Files\dotnet\sdk] 2.2.402 [C:\Program Files\dotnet\sdk] 3.1.426 [C:\Program Files\dotnet\sdk] 5.0.408 [C:\Program Files\dotnet\sdk] 6.0.321 [C:\Program Files\dotnet\sdk] 6.0.418 [C:\Program Files\dotnet\sdk] 7.0.115 [C:\Program Files\dotnet\sdk] 7.0.203 [C:\Program Files\dotnet\sdk] 8.0.100 [C:\Program Files\dotnet\sdk] 8.0.101 [C:\Program Files\dotnet\sdk] .NET runtimes installed: Microsoft.AspNetCore.All 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.App 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 7.0.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 7.0.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 8.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 8.0.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 2.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 7.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 7.0.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 8.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 8.0.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 7.0.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 7.0.15 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 8.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 8.0.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Other architectures found: x86 [C:\Program Files (x86)\dotnet] registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation] Environment variables: Not set global.json file: Not found Learn more: https://aka.ms/dotnet/info Download .NET: https://aka.ms/dotnet/download ```
horato commented 9 months ago

You can somewhat work around this issue by adding this line to .csproj of the nuget project <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>

Tripletri commented 9 months ago

You can somewhat work around this issue by adding this line to .csproj of the nuget project <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>

Thanks for the tip. With this approach, Microsoft.Build.Framework.dll, Microsoft.Build.Utilities.Core.dll, etc. are also included, judging by the comments in the example project, we want to avoid this

horato commented 9 months ago

You can somewhat work around this issue by adding this line to .csproj of the nuget project <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>

Thanks for the tip. With this approach, Microsoft.Build.Framework.dll, Microsoft.Build.Utilities.Core.dll, etc. are also included, judging by the comments in the example project, we want to avoid this

The README on the project seems a bit outdated. Here's a different version that should address this issue. The trick is to add ExcludeAssets="Runtime" to the Microsoft.Build.Utilities.Core PackageReference https://github.com/MicrosoftDocs/visualstudio-docs/blob/main/docs/msbuild/tutorial-custom-task-code-generation.md

Tripletri commented 9 months ago

Yes, seems like a good solution, thanks @horato

Solution

  1. Add <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
  2. Add ExcludeAssets="Runtime" to Microsoft.Build.Utilities.Core
Final .csproj file should look like this: netstandard2.0 1.0.0 AppSettingStronglyTyped John Generates a strongly typed setting class base on a txt file MyTags Copyright ©Contoso 2022 true $(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage tasks NU5100 embedded true true

P.S. I don't want to close the issue until the documentation is updated