CsWinRT
CsWinRT copied to clipboard
NativeAOT - Windows.System.DispatcherQueue.TryEnqueue fails
Disclaimer Before anyone decides to tell me in the comments that NativeAOT is currently not supported, I know that.
Describe the bug
Windows.System.DispatcherQueue.TryEnque
throws an exception in a NativeAOT program.
To Reproduce
- Create a simple .NET 7 Console App
var dispatcherQueueController = Windows.System.DispatcherQueueController.CreateOnDedicatedThread();
dispatcherQueueController.DispatcherQueue.TryEnqueue(LoadUri);
Console.ReadLine();
static async void LoadUri()
{
await Windows.System.Launcher.LaunchUriAsync(new("https://google.com"));
}
- Edit the
.csproj
file in such a way to enable NativeAOT as shown here: https://docs.microsoft.com/en-us/dotnet/core/deploying/native-aot/ - Add the CsWinRT dependency and make the .NET version compatible (example:
<TargetFramework>net7.0</TargetFramework>
-><TargetFramework>net7.0-windows10.0.22621.0</TargetFramework>
) - If dotnet decides that it doesn't want to support .NET 7 then make a
global.json file
:
{
"sdk": {
"version": "7.0.100-preview.7.22377.5"
}
}
- Publish your project (so that it actually uses AOT):
dotnet publish -r win-x64 -c Release
- Run it Current Result:
Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
at WinRT.TypeExtensions.GetAbiToProjectionVftblPtr(Type) + 0x36
at WinRT.ComWrappersSupport.GetInterfaceTableEntries(Type) + 0x9b
at WinRT.DefaultComWrappers.<>c.<ComputeVtables>b__7_0(Type) + 0x48
at System.Runtime.CompilerServices.ConditionalWeakTable`2.GetValueLocked(TKey, ConditionalWeakTable`2.CreateValueCallback) + 0x26
at System.Runtime.CompilerServices.ConditionalWeakTable`2.GetValue(TKey, ConditionalWeakTable`2.CreateValueCallback) + 0x3e
at WinRT.DefaultComWrappers.ComputeVtables(Object, CreateComInterfaceFlags, Int32&) + 0x71
at System.Runtime.InteropServices.ComWrappers.CreateCCW(Object, CreateComInterfaceFlags) + 0x36
at System.Runtime.InteropServices.ComWrappers.<>c__DisplayClass25_0.<GetOrCreateComInterfaceForObject>b__0(Object) + 0x1c
at System.Runtime.CompilerServices.ConditionalWeakTable`2.GetValueLocked(TKey, ConditionalWeakTable`2.CreateValueCallback) + 0x26
at System.Runtime.CompilerServices.ConditionalWeakTable`2.GetValue(TKey, ConditionalWeakTable`2.CreateValueCallback) + 0x3e
at System.Runtime.InteropServices.ComWrappers.GetOrCreateComInterfaceForObject(Object, CreateComInterfaceFlags) + 0xa8
at WinRT.ComWrappersSupport.CreateCCWForObjectForABI(Object, Guid) + 0x40
at WinRT.MarshalDelegate.CreateMarshaler2(Object, Guid, Boolean) + 0x8a
at ABI.Windows.System.DispatcherQueueHandler.CreateMarshaler2(DispatcherQueueHandler) + 0x63
at ABI.Windows.System.IDispatcherQueueMethods.TryEnqueue(IObjectReference, DispatcherQueueHandler) + 0x51
at Program.<Main>$(String[]) + 0x6e
at TEST.NativeAOT_WinRT!<BaseAddress>+0x2d8ab3
[process exited with code 3912227546 (0xe92fdada)]
Expected behavior
Running the program "normally" (not publishing) and/or with NativeAOT should work just fine (opens google.com
).
Version Info
Framework: .NET 7 preview 7
Packages: Microsoft.Windows.CsWinRT Version="2.0.0"
Additional context
As discussed here: #373, the cause for this is IL Trimming. IL Trimming is a requirement in .NET 7 NativeAOT. I created this issue because my project heavily relies on Native AOT and CsWinRT. Some APIs though (most of them are related to UI) require the executing code to be in a ASTA thread, therefore Windows.System.DispatcherQueue
. This issue causes many APIs to become unusable in CsWinRT.
A possible solution is not to rely on CsWinRT but instead create your own projection types and marshaller code (COMWrappers). The winmd files can provide the type information of interfaces. Even with CsWinRT 2.0 which supports IL trimming, it still won't work with NativeAOT because of #1248.
Thank you for your reply. Well I guess I have to wait then, so I hope that it will get fixed eventually... ┐( ∵ )┌
@CXCubeHD FYI you could also just copy the code from here (https://github.com/microsoft/CsWinRT/pull/1058) and it should work just fine on NativeAOT as well 🙂
@Sergio0694 Thank you I will look into it!