ICompositorDesktopInterop throws exception in TFM .NET 5

499 views Asked by At

I was trying to port a C# code from .NET 4.8 to .NET 5, older version of .NET was using Microsoft.Windows.SDK.Contracts, In .NET 5 Microsoft.Windows.SDK.Contracts is replaced by Target Framework Monikers (TFMs) I used the same code an tried to cast the compositor to ICompositorDesktopInterop but it throws exception :

System.PlatformNotSupportedException: 'Marshalling as IInspectable is not supported in the .NET runtime.'

Here is the code:

private readonly object _dispatcherQueue;
private readonly ICompositorDesktopInterop _compositorDesktopInterop;
private ICompositionTarget compositionTarget;
public Compositor compositor;

private void InitComposition(IntPtr hwnd) 
{
  ICompositorDesktopInterop interop;
  compositor = new Compositor();
  interop = compositor.As < ICompositorDesktopInterop > ();
  interop.CreateDesktopWindowTarget(hwnd, true, out compositionTarget);
  compositionTarget.Root = compositor.CreateSpriteVisual();
}

This is the Com Interface definition that i have used:

[ComImport]
[Guid("29E691FA-4567-4DCA-B319-D0F207EB6807")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ICompositorDesktopInterop 
{
  void CreateDesktopWindowTarget(IntPtr hwndTarget, bool isTopmost, out ICompositionTarget test);
}

[ComImport]
[Guid("A1BEA8BA-D726-4663-8129-6B5E7927FFA6")]
[InterfaceType(ComInterfaceType.InterfaceIsIInspectable)]
public interface ICompositionTarget 
{
  Windows.UI.Composition.Visual Root 
  {
    get;
    set;
  }
}

Why is it not working with TFM ? Is there something I missed ?

1

There are 1 answers

0
trickymind On BEST ANSWER

The issue with TFM can be solved by using DirectN or by using InteropCompositor

For InteropCompositor:

Set the TargetFramework in the project file

<TargetFramework>net5.0-windows10.0.19041.0</TargetFramework>

and in your code use

Compositor compositor = new Compositor();
ICompositorDesktopInterop interop = compositor.TryAs<ICompositorDesktopInterop>();
interop.CreateDesktopWindowTarget(hwnd, true, out var target).ThrowOnError();
ICompositionTarget compositionTarget = (ICompositionTarget)target;

Note: Don't forget to create DispatcherQueueController on MainWindow Constructor.

All Credits to : Simon Mourier