dotnet / wpf

WPF is a .NET Core UI framework for building Windows desktop applications.
MIT License
7.07k stars 1.16k forks source link

"Microsoft.Extensions.Configuration.Binder" v8.x causes WPF self-contained publish failed #9660

Open tp1415926535 opened 2 months ago

tp1415926535 commented 2 months ago

Description

Microsoft.Extensions.Configuration.Binder v8.0.0 and above from nuget causes WPF self-contained publish failed, and once return to 7.x version, everything works fine. This doesn't happen with console projects or API projects.

Other packages (like Microsoft.Extensions.Hosting 8.0.0) that reference these version of the dll will also cause the WPF self-contained publish failed.

Reproduction Steps

  1. Create an empty .NET6 (or other version) WPF project.
  2. Add the latest Microsoft.Extensions.Configuration.Binder (v8.0.2) in the nuget package manager.
  3. Publish to folder with self-contained deployment.

Expected behavior

Publish Successfully.

Actual behavior

Publish failed with nothing details.
C:\Users\%UserName%\AppData\Local\Temp\tmpXXXXX.tmp only show:

System.AggregateException: One or more errors occurred. ---> Microsoft.WebTools.Shared.Exceptions.WebToolsException: Build failed. Check the Output window for more details.
--- End of inner exception stack trace ---
---> (Inner Exception #0) Microsoft.WebTools.Shared.Exceptions.WebToolsException: Build failed. Check the Output window for more details.<---

Microsoft.WebTools.Shared.Exceptions.WebToolsException: Build failed. Check the Output window for more details.

Regression?

Just use back to version 7.x (e.g. 7.0.4) and release it independently and it will work.

Known Workarounds

Fallback to the version of the this package, or publish framework-dependent and portable.

Configuration

.NET6 or .NET7 and so on, whatever.

Other information

No response

ericstj commented 2 months ago

What version of Visual Studio or .NET SDK are you using? Have you tried using the dotnet CLI to see if the same problem occurs? Did you notice any warnings when building that might be treated as errors when you're publishing?

I tried your repro steps as follows and they worked fine for me:

dotnet new wpf -f net6.0
dotnet add package Microsoft.Extensions.Configuration.Binder
dotnet publish --self-contained

Worked just fine for me. image

Please provide answers to above questions and also a minimal repro and logs if you can share them.

Thanks!

tp1415926535 commented 2 months ago

What version of Visual Studio or .NET SDK are you using? Have you tried using the dotnet CLI to see if the same problem occurs? Did you notice any warnings when building that might be treated as errors when you're publishing?

I tried your repro steps as follows and they worked fine for me:

dotnet new wpf -f net6.0
dotnet add package Microsoft.Extensions.Configuration.Binder
dotnet publish --self-contained

Worked just fine for me. image

Please provide answers to above questions and also a minimal repro and logs if you can share them.

Thanks!

I tried your command and it did work properly. But in Visual Studio 2022 right click project - Publish, target select folder, set to self-contained deployment and click publish and it fails.

Also, I've noticed that as long as I've run FolderProfile.pubxml with the dotnet command, like dotnet publish "E:\Microsoft Visual Studio\Projects\Test" "/p:PublishProfile=E:\Microsoft Visual Studio\Projects\Test\Properties\PublishProfiles\FolderProfile.pubxml" After that I can also publish it directly in VS successfully, which is very strange. And then if change the target runtime from win-x64 to win-x86( or something else) in VS, it will still publish failed.

tarekgh commented 2 months ago

@tp1415926535 I have tried it in VS and I didn't hit any error (as long as I am specifying the language version in the project). Here is the csproj I have:

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

  <PropertyGroup>
      <OutputType>WinExe</OutputType>
      <TargetFramework>net6.0-windows</TargetFramework>
      <Nullable>enable</Nullable>
      <ImplicitUsings>enable</ImplicitUsings>
      <UseWPF>true</UseWPF>

      <LangVersion>12</LangVersion>

      <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
      <EnableConfigurationBindingGenerator>true</EnableConfigurationBindingGenerator>

      <PublishSingleFile>true</PublishSingleFile>
      <SelfContained>true</SelfContained>
      <RuntimeIdentifier>win-x64</RuntimeIdentifier>
  </PropertyGroup>

  <ItemGroup>
        <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.2" />
  </ItemGroup>  
</Project>

Here is the output of publishing operation:

Build started at 4:40 PM...
1>------ Build started: Project: WpfApp1, Configuration: Release Any CPU ------
1>WpfApp1 -> D:\Users\User\source\repos\WpfApp1\bin\Release\net6.0-windows\win-x64\WpfApp1.dll
2>------ Publish started: Project: WpfApp1, Configuration: Release Any CPU ------
2>Determining projects to restore...
2>All projects are up-to-date for restore.
2>WpfApp1 -> D:\Users\User\source\repos\WpfApp1\bin\Release\net6.0-windows\win-x64\WpfApp1.dll
2>WpfApp1 -> D:\Users\User\source\repos\WpfApp1\bin\Release\net6.0-windows\publish\
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
========== Build completed at 4:40 PM and took 08.169 seconds ==========
========== Publish: 1 succeeded, 0 failed, 0 skipped ==========
========== Publish completed at 4:40 PM and took 08.169 seconds ==========

Also, I have .NET 9.0 preview SDK installed on my machine which is used by VS in compiling/publishing. I tried to force .NET 8 SDK too through adding global.json file

{
  "sdk": {
    "rollForward": "latestFeature",
    "version": "8.0.8"
  }
}

and both 8.0 and 9.0 SDKs worked fine.

Could you please review if you have exact csproj I shared here. If you have similar project and environment, I suggest you enable diagnostic output Tools->Options->Projects and Solutions->Build And Run and select Diagnostic option for the drop list of MSBuild project build output verbosity then send the log of the output.

tp1415926535 commented 2 months ago
      <LangVersion>12</LangVersion>

@tarekgh Yes, I found that it's true that adding the LangVersion tag in PropertyGroup can succeed in self-contained publishing, while the default csproj doesn't have:


<Project Sdk="Microsoft.NET.Sdk">
WinExe net6.0-windows enable enable true


If the csproj delete the LangVersion flag, and after deleting the **obj** folder, self-contained publishing in VS will fail. I think it's easy to reproduce, but still attached the failed publish output in here: [build-error-Log.txt](https://github.com/user-attachments/files/16775571/build-error-Log.txt)

It looks like the my publish issue is well resolved now, but why is this ‘Binder 8.0.x’ package the only one that needs to be forced to add the language version, maybe it's using too high syntax? Of all the nuget packages I've used only it causes this.
tarekgh commented 2 months ago

It looks like the my publish issue is well resolved now, but why is this ‘Binder 8.0.x’ package the only one that needs to be forced to add the language version, maybe it's using too high syntax?

Right. The configuration source gen now is using a new compiler feature called interceptors which require v12 of the language.

ericstj commented 2 months ago

LangVersion is only required when you are using the source generator from Configuration.Binder 8.0. The source generator works by intercepting calls to the binder and replacing them with compile-time generated code for your configuration types (rather than using reflection). The interceptors feature is something that is only available in C# 12 which is the reason for this warning.

I was able to reproduce the error, it's due to WPF's GenerateTemporaryTargetAssembly. This target is trying to rerun compilation and only running some of the build targets. It tries to pass in the analyzers from the outer build, which omit this analyzer (since it's not enabled) but then the nested build inside GenerateTemporaryTargetAssembly reruns ResolveLockFileAnalyzers which adds it back. Unfortunately that nested build does not import any targets from NuGet packages, so it does not run the target from Microsoft.Extensions.Configuration.Binder that removes the analyzer when it's not enabled.

This problem is essentially due to the same reason as https://github.com/dotnet/wpf/issues/9589#issuecomment-2293747041

We need WPF to investigate how GenerateTemporaryTargetAssembly is handling these cases and determine how to fix this.

For now you can either set LangVersion as a workaround, or if you don't want to do that, you could add a target that removes this generator (as the package itself does):

  <!-- The below target is copied from the  Microsoft.Extensions.Configuration.Binder.  
       It's required because WPF's GenerateTemporaryTargetAssembly will create a temporary project that 
       resolves analyzers from NuGet packages but doesn't import any of the packages props or targets.
       A condition is added that checks for _TargetAssemblyProjectName which is set by WPF's GenerateTemporaryTargetAssembly.  -->
  <Target Name="_Microsoft_Extensions_Configuration_Binder_RemoveAnalyzer_WORKAROUND"
          Condition="'$(EnableConfigurationBindingGenerator)' != 'true' AND '$(_TargetAssemblyProjectName)' != ''"
          AfterTargets="ResolvePackageDependenciesForBuild;ResolveNuGetPackageAssets">

    <ItemGroup>
      <Analyzer Remove="@(Analyzer->WithMetadataValue('NuGetPackageId', 'Microsoft.Extensions.Configuration.Binder'))" />
    </ItemGroup>
  </Target>
ergunr commented 2 months ago

Holla

Envoyé de mon iPhone

Le 28 août 2024 à 22:08, 纵码过河山 @.***> a écrit :



Description

Microsoft.Extensions.Configuration.Binder v8.0.0 and above from nuget causes WPF self-contained publish failed, and once return to 7.x version, everything works fine. This doesn't happen with console projects or API projects.

Other packages (like Microsoft.Extensions.Hosting 8.0.0) that reference these version of the dll will also cause the WPF self-contained publish failed.

Reproduction Steps

  1. Create an empty .NET6 (or other version) WPF project.
  2. Add the latest Microsoft.Extensions.Configuration.Binder (v8.0.2) in the nuget package manager.
  3. Publish to folder with self-contained deployment.

Expected behavior

Publish Successfully.

Actual behavior

Publish failed with nothing details. C:\Users\%UserName%\AppData\Local\Temp\tmpXXXXX.tmp only show:

System.AggregateException: One or more errors occurred. ---> Microsoft.WebTools.Shared.Exceptions.WebToolsException: Build failed. Check the Output window for more details. --- End of inner exception stack trace --- ---> (Inner Exception #0) Microsoft.WebTools.Shared.Exceptions.WebToolsException: Build failed. Check the Output window for more details.<---

Microsoft.WebTools.Shared.Exceptions.WebToolsException: Build failed. Check the Output window for more details.

Regression?

Just use back to version 7.x (e.g. 7.0.4) and release it independently and it will work.

Known Workarounds

Fallback to the version of the this package, or publish framework-dependent and portable.

Configuration

.NET6 or .NET7 and so on, whatever.

Other information

No response

— Reply to this email directly, view it on GitHubhttps://github.com/dotnet/wpf/issues/9660, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AUW2LQ4TEUWL27S5JNJAZBTZTYN3FAVCNFSM6AAAAABNI5FPIKVHI2DSMVQWIX3LMV43ASLTON2WKOZSGQ4TEOBQG44TCMA. You are receiving this because you commented.Message ID: @.***>