Skip to content

Design-time build (DesignTimeBuild=true) fails with NETSDK1022 duplicate Compile ('.g.cs') in the _wpftmp project on .NET 10 SDK when XAML references a same-project type #11775

Description

@anagnorisis2peripeteia

Description

On the .NET 10 SDK, running MSBuild with -p:DesignTimeBuild=true on a WPF project whose XAML references a same-project type fails with:

Microsoft.NET.Sdk.DefaultItems.Shared.targets(190,5): error NETSDK1022: Duplicate 'Compile' items were included. The .NET SDK includes 'Compile' items from your project directory by default. ... The duplicate items were: '...\obj\Debug\net8.0-windows\LocalControl.g.cs'; '...\obj\Debug\net8.0-windows\GeneratedInternalTypeHelper.g.cs' [...\WpfLib_xxxxx_wpftmp.csproj]

The error is raised from the temporary markup-compile project (*_wpftmp.csproj, i.e. the GenerateTemporaryTargetAssembly pass) — the generated .g.cs files end up in its Compile items twice. The same command succeeds on the .NET 8 SDK, succeeds on the 10 SDK without the property, and a normal (non-design-time) build succeeds on both.

This breaks design-time analysis tooling generally: I hit it via Stryker.NET/Buildalyzer, whose project analysis performs an instrumented design-time build (see stryker-mutator/stryker-net#3701 for the investigation trail).

Reproduction Steps

WpfLib/WpfLib.csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0-windows</TargetFramework>
    <UseWPF>true</UseWPF>
  </PropertyGroup>
</Project>

WpfLib/MyConverter.cs:

using System; using System.Globalization; using System.Windows.Data;
namespace WpfLib
{
    public class MyConverter : IValueConverter
    {
        public object Convert(object v, Type t, object p, CultureInfo c) => v;
        public object ConvertBack(object v, Type t, object p, CultureInfo c) => v;
    }
}

WpfLib/LocalControl.xaml (the key part — it references the local type, which triggers the temp-assembly pass):

<UserControl x:Class="WpfLib.LocalControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfLib">
  <UserControl.Resources>
    <local:MyConverter x:Key="conv"/>
  </UserControl.Resources>
  <TextBlock Text="{Binding Converter={StaticResource conv}}"/>
</UserControl>

WpfLib/LocalControl.xaml.cs:

using System.Windows.Controls;
namespace WpfLib { public partial class LocalControl : UserControl { public LocalControl() { InitializeComponent(); } } }

Then:

dotnet msbuild WpfLib\WpfLib.csproj /restore /t:Clean;Build -p:DesignTimeBuild=true

Expected behavior

The design-time build succeeds (as it does on the .NET 8 SDK), or at least does not double-include the WPF-generated .g.cs files in the temporary project.

Actual behavior

error NETSDK1022: Duplicate 'Compile' items for LocalControl.g.cs and GeneratedInternalTypeHelper.g.cs, raised in WpfLib_*_wpftmp.csproj; exit code 1.

Regression?

Yes. The identical project and command succeed on SDK 8.0.420; they fail on SDK 10.0.301.

Additional data points:

  • Only reproduces when the XAML references a local (same-project) type — with only package/framework xmlns references (no temp-assembly pass), the design-time build succeeds.
  • DesignTimeBuild=true alone is sufficient; I bisected the full property set a design-time analyzer (Buildalyzer) passes, one property at a time, and every other property is innocent.
  • DefaultItemExcludes in the failing build correctly contains obj\** for the real project; the duplication happens in the temp project's context.

Known Workarounds

Pin the .NET 8 SDK via global.json for the analysis run, or avoid the design-time property set (a normal build is unaffected).

Impact

Any tool that performs design-time builds of WPF projects (Buildalyzer, Stryker.NET, and similar analyzers) fails on .NET 10 SDK for projects with local-type XAML references.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions