Home > Software design >  .Net - WPF .Net Core 3.1 - CapturePicker The application called an interface that was marshalled for
.Net - WPF .Net Core 3.1 - CapturePicker The application called an interface that was marshalled for

Time:01-27

Currently I'm trying to develop a solution uses .Net Core 3.1 and it's responsible to select multiple capture windows, to be shared when focused.

I've made it work using a list, but I think would be much more elegant and user friendly if I've a picker that shows a preview of the window before selecting.

I'm trying to use GraphicsCapturePicker but I'm getting the following error:

The application called an interface that was marshalled for a different thread enter image description here

Here is the following methods that I'm using to open the picker:

public async void OpenCapturePicker(object sender, RoutedEventArgs e)
{
    Console.WriteLine("OpenCapturePicker");
    await Dispatcher.InvokeAsync(OpenCapturePicker);

}
private async void OpenCapturePicker()
{
    var picker = new GraphicsCapturePicker();

    picker.SetWindow(_capturableWindowHandle);
    var item = await picker.PickSingleItemAsync();
    if (item == null) return;
    //rest of code
}

The _capturableWindowHandle is defined in the constructor of the class like:

public SomeClass(){
 _capturableWindowHandle = new WindowInteropHelper(this).Handle;
}

Also I've an extension class that allows me to use the SetWindow method

public  static class CaptureHelper
{
    static readonly Guid GraphicsCaptureItemGuid = new Guid("79C3F95B-31F7-4EC2-A464-632EF5D30760");
    public static GraphicsCaptureItem CreateItemForWindow(IntPtr windowInteropHandler)
    {
        var factory = WindowsRuntimeMarshal.GetActivationFactory(typeof(GraphicsCaptureItem));
        var interop = (IGraphicsCaptureItemInterop) factory;
        var itemPointer = interop.CreateForWindow(windowInteropHandler, GraphicsCaptureItemGuid);
        var item = Marshal.GetObjectForIUnknown(itemPointer) as GraphicsCaptureItem;
        Marshal.Release(itemPointer);

        return item;
    }
    public static void SetWindow(this GraphicsCapturePicker picker, IntPtr hwnd)
    {
        var interop = (IInitializeWithWindow)(object)picker;
        interop.Initialize(hwnd);
    }
}

Update

Here is the link of the branch that I'm using to add this feature

Any ideas?

CodePudding user response:

Update:

This Code worked for me:

    if (!GraphicsCaptureSession.IsSupported()) {
        Trace.WriteLine("No Capture Support");
        return;
    }

    // var picker = new GraphicsCapturePicker();
    // picker.SetWindow(_capturableWindowHandle);
    // var item = await picker.PickSingleItemAsync();

    var interopWindow = new WindowInteropHelper(this);
    var hwnd = interopWindow.Handle;
    var picker = new GraphicsCapturePicker();
    picker.SetWindow(hwnd);
    var item = await picker.PickSingleItemAsync();
    if (item == null) {
        return;
    }

    _windowCaptureService.StartCapture(item, _capturableWindowHandle);

Be aware: This code is not doing anything if you put a breakpoint in it... Maybe it is initialized with the debugger window in this case...??? But without breakpoints it is working on my Windows 10 machine.

First Answer:

The error message is telling you, that something was created on a different thread than it is used later on. I don't see your complete code here, but you should check, if you e.g. call the constructor of SomeClass in the same thread as

picker.SetWindow(_capturableWindowHandle);

Same thing with all other code involved here or prior to OpenCapturePicker...

  • Related