dotnet / wpf

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

BamlLocalizer throws exception reading BAML streams in .NET Core #7245

Open ericcdub opened 2 years ago

ericcdub commented 2 years ago

I have read elsewhere that the LocBaml utility doesn't work either when upgraded to .NET 6 https://tomaskohl.com/code/2020-06-24/localizing-wpf-app-on-net-core/ and there is an open issue here to port it to .NET core here https://github.com/microsoft/WPF-Samples/issues/85 but it would be good to hear this from the horse's mouth as it were.

lindexi commented 2 years ago

Reference: https://github.com/dotnet/wpf/issues/1480 https://github.com/dotnet/wpf/issues/6477

ericcdub commented 2 years ago

In the end, I managed to extract BAML from an assembly by calling AssemblyLoadContext.EnterContextualReflection(myAssembly);

This will cause the runtime to use the assembly's own load context as the reflection-only context, meaning BamlLocalizer will try to load the assembly into that same context. I'm not sure if this would have unintended side effects, but so far so good.

It would also tally with what I read here.

Kuldeep-MS commented 2 years ago

@ericcdub - Can you please attach the repro for the issue?

ericcdub commented 2 years ago

@ericcdub - Can you please attach the repro for the issue?

Hi @Kuldeep-MS

The issue reproduces when using the LocBaml tool as described in this help page https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/how-to-localize-an-application.

LocBaml uses BinaryLocalizer in ResourceGenerator.GenerateBamlStream, but is not AssemblyLoadContext-aware so it throws the same exception

The LocBaml project is still targeting .NET Framework, so either create a new .NET project and copy the source in or else use the .NET Upgrade assistant to migrate it.

Let me know if you need any more info.

Thanks

harshit7962 commented 1 year ago

This issue is actually blocked on unavailability of several methods from ModuleBuilder and AssemblyBuilder which prevents us to create methods that can actually emit the correct target assemblies.

h3xds1nz commented 1 month ago

@harshit7962 As I've done it here, you do not need to generate dynamic assembly / module at all, just build it directly via metadata builder, after all it's just a resource assembly.

The original code used dynamic assemblies (RunAndSave) just because in 2005 there simply were no other options, however MetadataBuilder and whole System.Reflection.Metadata with the methods required to make this work was available earlier than WPF was even ported open source so this could have been done years ago.

So imho issue-type-tracking-external is not the correct label here. Since the issue is in Xaml/Baml readers/parsers not being assembly-context aware and requiring everything to be done in the Default context to work properly.