Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.NET 9 SDK WPF build broken with AssemblyName in Directory.Build.props #10068

Open
candritzky opened this issue Nov 13, 2024 · 6 comments
Open

Comments

@candritzky
Copy link

candritzky commented Nov 13, 2024

Description

We have a pretty complex solution with a central Directory.Build.props file.
This Directory.Build.props file contains - among other stuff - a RootNamespace property that sets a default root namespace according to our conventions.

Something similar to this:

  <PropertyGroup>
    <RootNamespace>MyCompanyName.MyProductName.$(MSBuildProjectName)</RootNamespace>
    <AssemblyName>$(RootNamespace)</AssemblyName>
  </PropertyGroup>

The goal of this is that our .csproj files have short names without a MyCompanyName.MyProductName. prefix, but the namespaces and generated assemblies should have this prefix.

This worked since years up to .NET SDK 8.0.403. But it's broken since 2024-11-13 when Visual Studio 17.12 (which brings .NET SDK 9.0.100) was installed. It breaks WPF builds if the Directory.Build.props file sets a RootNamespace and/or a custom AssemblyName MSBuild property. It works if the property is moved to the WPF project's .csproj file. But it really needs to be moved, i.e. removed from the central Directory.Build.props file.

Something seems to be broken in the WPF XAML compile process.

As a workaround, I would have to comment out the <AssemblyName> property in Directory.Build.props, but this would break (or at least change) the output of all our other projects.

Reproduction Steps

Please see that attached ZIP file for a minimal repro.
Uncomment the <AssemblyName> tag in Directory.Build.props and the (clean) build will fail.

MyWpfApp.zip

Expected behavior

WPF apps should build without errors in .NET SDK 9 as they did in .NET SDK 8.

Actual behavior

Building with .NET SDK 9 is broken if there is a Directory.Build.props file with a custom <AssemblyName> property.

Regression?

Yes, it worked up to .NET SDK 8.0.403. Broken since 9.0.100.

Known Workarounds

No response

Impact

No response

Configuration

No response

Other information

No response

@zlatanov
Copy link

zlatanov commented Nov 14, 2024

I can reproduce the same issue as well. We use AssemblyName identically to how @candritzky explained.

WORKAROUND

Instead of overriding the AssemblyName in the csproj file, create a Directory.Build.props inside the WPF project and set the AssemblyName there.

<Project>
    <PropertyGroup>
        <AssemblyName>my-wpf-app</AssemblyName>
    </PropertyGroup>
</Project>

@zlatanov
Copy link

For the WPF team:

The task GenerateTemporaryTargetAssembly generates assembly with name which comes from the parent Directory.Build.props and not the one that is defined in the WPF csproj file.

@zlatanov
Copy link

zlatanov commented Nov 14, 2024

<IncludePackageReferencesDuringMarkupCompilation>false</IncludePackageReferencesDuringMarkupCompilation>

Also fixes the problem. Which means that something in ExecuteGenerateTemporaryTargetAssemblyWithPackageReferenceSupport method is different than ExecuteLegacyGenerateTemporaryTargetAssembly.

The only real difference I see is how AssemblyName is passed to BuildEngine.BuildProjectFile. In the legacy version it is passed as properties, whereas in the new version it is written to the temp csproj file, and as far as I can see it is written correctly, but the BuildEngine ignores it for some reason.

@candritzky
Copy link
Author

candritzky commented Nov 14, 2024

Instead of overriding the AssemblyName in the csproj file, create a Directory.Build.props inside the WPF project and set the AssemblyName there.

Thank you so much!

Just wanted to confirm that this workaround also works for me. I refined the solution a bit with an important of the ancestor Directory.Build.props file as shown below, so that I don't loose all my other global settings.

<Project>

  <Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$([System.IO.File.Path]::Combine('..', $(MSBuildThisFileDirectory)'))" />

  <PropertyGroup>
    <AssemblyName>my-wpf-app</AssemblyName>
  </PropertyGroup>
</Project>

@candritzky
Copy link
Author

false
Also fixes the problem. Which means that something in ExecuteGenerateTemporaryTargetAssemblyWithPackageReferenceSupport method is different than ExecuteLegacyGenerateTemporaryTargetAssembly.

Unfortunately this workaround does not work for me. It breaks other things in the build process.
For example, it breaks the Compile-time logging source generation feature because the source generator seems to be effectively disabled.

public static partial class Log
{
    [LoggerMessage(
        EventId = 0,
        Level = LogLevel.Critical,
        Message = "Could not open socket to `{HostName}`")]
    public static partial void CouldNotOpenSocket(
        ILogger logger, string hostName);
}

Results in

error CS8795: Partial method 'Log.CouldNotOpenSocket(ILogger, string)' must have an implementation part because it has accessibility modifiers.

@zlatanov
Copy link

Unfortunately this workaround does not work for me. It breaks other things in the build process.
For example, it breaks the Compile-time logging source generation feature because the source generator seems to be effectively disabled.

Yeah, I know. I just noted that, so the code owners have a starting point when trying to find out the root cause.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants