microsoft / CsWinRT

C# language projection for the Windows Runtime
MIT License
555 stars 107 forks source link

Allow WinRT.Runtime.dll to be loaded in a custom AssemblyLoadContext #1371

Open msftrubengu opened 1 year ago

msftrubengu commented 1 year ago

Describe the bug Our winget PowerShell modules have their own custom AssemblyLoadContext to load binaries to avoid dependency conflicts. This is the recommended solution from the PowerShell team.

However, loading WinRT.Runtime.dll into different custom ALCs result in System.InvalidOperationException:“Attempt to update previously set global instance.”. Forcing me to special case it and load it in the default context.

This works ok if all the PowerShell modules uses the same WinRT.Runtime.dll version but there are other modules that can use a different version, like BurnToast that uses 1.1.0.0, which can't be loaded in the same session.

This was apparently fixed some time ago but it came back based on #623

To Reproduce Load same version of WinRT.Runtime.dll into the default context and a custom ALC.

Expected behavior WinRT.Runtime.dll should load in both contexts.

JohnMcPMS commented 2 weeks ago

Note to anyone who may be dealing with similar.

Moving to CsWinRT 2.1+ can affect your ALC setup as #1390 moved the component loading into WinRT.Runtime.dll from the projection binary. Our solution has been to continue to load WinRT.Runtime.dll into the default context, but this means that the unmanaged load now happens in the default context rather than our custom context. This can lead to a Class not registered error due to not finding the component binary.

The simple solution is to add a ResolvingUnmanagedDll event handler to the default context. We had previously had no need as all of our unmanaged binaries were being loaded from managed ones already loaded into our custom context.