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

KeyNotFoundException thrown by SourceGenerator for a nested public struct in an internal class and only showing as a build warning #1624

Closed
xyzzer opened this issue May 21, 2024 · 1 comment
Labels
authoring Related to authoring feature work bug Something isn't working

Comments

@xyzzer
Copy link

xyzzer commented May 21, 2024

Summary
I have a WinUI3 C++/WinRT (WindowsAppSDK) app "CppHost" with most of the XAML UI implemented in a separate C# DLL "CsUiLibrary".
I also have a separate C#-based test app "CsUiTestHost" that loads the same DLL to test the different parts of the UI it implements that helps speed up some prototyping.
I was trying to add some functionality in CsUiLibrary the that used p/invoke into some old Win32 APIs and everything was working great in the CsUiTestHost, but at one point I started integrating the new UI into the CppHost and started hitting issues like:

Microsoft.UI.Xaml.dll!00007FFF57B03106: 80040154 - Class not registered
Unhandled exception at 0x00007FFF57D95175 (Microsoft.ui.xaml.dll) in CppHost.exe: 0xC000027B: An application-internal exception has occurred (parameters: 0x000001FB60348740, 0x0000000000000004).

After hours of adding and removing various parts of the code I noticed there was this not-seen-before warning in the output of the CsUiLibrary that didn't scream at me or break the build that only showed with the new code, which helped narrow things down a bit since I could now keep undoing or re-adding bits of code checking for which parts cause the warning to show up or disappear:

1>CSC : warning CS8785: Generator 'SourceGenerator' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type 'KeyNotFoundException' with message 'The given key was not present in the dictionary.'.

It turns out the issue triggers when I define an internal class (I use a lot of internal classes to implement things in CsUiLibrary without cryptic/hidden projection errors, but some things I need to make public anyways because XAML C++/C# compilers likes it that way) and a nested public struct inside of it. Now, marking the nested struct as internal - fixes the problem and the problem only occurs if the struct is tagged with StructLayoutAttribute.

To Reproduce
Create WinUI 3 C++ Desktop app and a C# WinUI 3 Desktop Class Library.
Reference the C# library from the C++ host app and add something like a UserControl in the library to display the C++ host app and F5-test to make sure it works fine at this stage.
Now add below class to the C# library:

namespace Foo.Interop
{
    internal static class Bar
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct Xyz
        {
            public int Abc;
        }
    }
}

This builds fine, but should show the error-as-warning KeyNotFoundException I mentioned earlier in the library build output and when you run the C++ host app now app - you get the unhandled "Class not registered" exception that crashes the app.

Expected behavior
This builds and runs fine in a C# host app, so the exception from SourceGenerator shouldn't occur.
I suspect there's a good reason why the WinUI class library msbuild project template hides the error without blocking the build, but maybe it's not a good enough reason or there should be an easier way to help match the runtime exception with an original error. That's likely more a WinUI problem than CsWinRT even if these things typically go in pair.

Version Info
C++ host lists these imports:

  <Import Project="..\packages\Microsoft.WindowsAppSDK.1.5.240404000\build\native\Microsoft.WindowsAppSDK.props" Condition="Exists('..\packages\Microsoft.WindowsAppSDK.1.5.240404000\build\native\Microsoft.WindowsAppSDK.props')" />
  <Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.240412.1\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.240412.1\build\native\Microsoft.Windows.CppWinRT.props')" />
  <Import Project="..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22621.3233\build\Microsoft.Windows.SDK.BuildTools.props" Condition="Exists('..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22621.3233\build\Microsoft.Windows.SDK.BuildTools.props')" />

C# library lists these details:

    <TargetFramework>net6.0-windows10.0.22621.0</TargetFramework>
    <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
    <RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
    <UseWinUI>true</UseWinUI>
    <CsWinRTComponent>true</CsWinRTComponent>

Additional context

@xyzzer xyzzer added the bug Something isn't working label May 21, 2024
@xyzzer xyzzer changed the title KeyNotFoundException thrown for a nested public struct in an internal class and only showing as a build warning KeyNotFoundException thrown by SourceGenerator for a nested public struct in an internal class and only showing as a build warning May 21, 2024
@manodasanW manodasanW added the authoring Related to authoring feature work label May 25, 2024
@asklar
Copy link
Member

asklar commented Jun 27, 2024

See #1202

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
authoring Related to authoring feature work bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants