MicrosoftEdge / WebView2Feedback

Feedback and discussions about Microsoft Edge WebView2
https://aka.ms/webview2
427 stars 51 forks source link

CoreWebView2.AddHostObjectToScript throws exception "The group or resource is not in the correct state to perform the requested operation." #2754

Open epaezrubio opened 1 year ago

epaezrubio commented 1 year ago

Description I'm trying to add a host object into a WebView2, but I'm getting the following exception:

The group or resource is not in the correct state to perform the requested operation.

Version SDK: Microsoft.Web.WebView2 version 1.0.1264.42 Runtime: 5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Edg/105.0.1343.27 Framework: UWP OS: Win10 version 10.0.19043 Build 19043

Repro Steps

This is the code that I'm running:

[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class Example
{
    public string Prop { get; set; } = "example";
}

namespace Example_UWP
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            InitializeComponent();
            InitializeAsync();
        }

        public async Task InitializeAsync()
        {
            await ExampleView.EnsureCoreWebView2Async();

            ExampleView.Source = new Uri("http://localhost:3000");
            ExampleView.CoreWebView2.OpenDevToolsWindow();

            ExampleView.CoreWebView2.AddHostObjectToScript("example", new Example());
        }
    }
}

After the exception, the host object is not available in chrome.webview.hostObjects or chrome.webview.hostObjects.sync.

I've tried different potential solutions such as:

david-risney commented 1 year ago

Which UI framework are you using? You say its a UWP app so I'm guessing you're using WinUI2 or WinUI3 and so you're using the WebView2 WinRT APIs, is that correct? If so, you need to use the directions for using WinRT with AddHostObjectToScript rather than the directions for using a .NET class.

It looks like the Example class has attributes to make it an IDispatch supporting .NET class which is what you need to do if you're using the WebView2 .NET APIs. However if you're using WinUI2 or WinUI3 those are WinRT, and so the WebView2 control is also WinRT and the WinRT type system has no way to reference .NET or other non-WinRT objects so you cannot pass in a .NET object but only a WinRT object to AddHostObjectToScript (or any other WinRT method). However, unlike .NET, WinRT also doesn't have any built-in reflection mechanism so we have the wv2winrt tool that's described in the above link to make it possible for WebView2 to dynamically inspect and call into WinRT types.

FANMixco commented 1 year ago

Which UI framework are you using? You say its a UWP app so I'm guessing you're using WinUI2 or WinUI3 and so you're using the WebView2 WinRT APIs, is that correct? If so, you need to use the directions for using WinRT with AddHostObjectToScript rather than the directions for using a .NET class.

It looks like the Example class has attributes to make it an IDispatch supporting .NET class which is what you need to do if you're using the WebView2 .NET APIs. However if you're using WinUI2 or WinUI3 those are WinRT, and so the WebView2 control is also WinRT and the WinRT type system has no way to reference .NET or other non-WinRT objects so you cannot pass in a .NET object but only a WinRT object to AddHostObjectToScript (or any other WinRT method). However, unlike .NET, WinRT also doesn't have any built-in reflection mechanism so we have the wv2winrt tool that's described in the above link to make it possible for WebView2 to dynamically inspect and call into WinRT types.

Hi @david-risney, most likely this is what @epaezrubio needed. However, this should be documented better. Currently, I felt like a bad joke because I had to guess a lot of code from this branch in Git mode: https://github.com/MicrosoftEdge/WebView2Samples/compare/uwp-wv2winrt-custom-csharp-winrt

image image

Why did the team not create a normal project sample? Or just share the normal branch? I am thankful that you share this branch because we could be in worst shape without your support. However, I believe it should be documented better.

I have spent several hours guessing several changes, but I finally made it work. Also, there should be maybe in the future a plugin or something to avoid the C++ lib. I don't code with C++ and had to install something extra just for adding a lib. The current approach is overcomplicated. Just some of the changes that I had to do:

  1. Add the WebView2 lib in my UWP project.
  2. Create the C++ project.
  3. Modify my 3rd party lib.
  4. Changed the logic from ms-appx-web:///Assets to core_wv2.SetVirtualHostNameToFolderMapping( "myapp.site", "Assets", CoreWebView2HostResourceAccessKind.Allow);
  5. Configure the 3rd party lib based on the code.

And other things, the worst is that is poorly documented all these steps. I had to guess multiple GitHub bugs and StackOverflow questions.

FANMixco commented 1 year ago

I wrote this full tutorial. I describe the full migration from WebView to WebView2 and all required changes:

https://supernovaic.blogspot.com/2022/10/from-webview-to-webview2-in-uwp.html

FabioSilvaOS commented 1 month ago

Which UI framework are you using? You say its a UWP app so I'm guessing you're using WinUI2 or WinUI3 and so you're using the WebView2 WinRT APIs, is that correct? If so, you need to use the directions for using WinRT with AddHostObjectToScript rather than the directions for using a .NET class.

It looks like the Example class has attributes to make it an IDispatch supporting .NET class which is what you need to do if you're using the WebView2 .NET APIs. However if you're using WinUI2 or WinUI3 those are WinRT, and so the WebView2 control is also WinRT and the WinRT type system has no way to reference .NET or other non-WinRT objects so you cannot pass in a .NET object but only a WinRT object to AddHostObjectToScript (or any other WinRT method). However, unlike .NET, WinRT also doesn't have any built-in reflection mechanism so we have the wv2winrt tool that's described in the above link to make it possible for WebView2 to dynamically inspect and call into WinRT types.

@david-risney, regarding "Which UI framework are you using?", is MAUI (BlazorWebView) considered "WinUI3" or ".NET"? Is there any solution for that yet? It is hilarious that in MAUI, Android and iOS WebViews works nicely, but we have problems with the Windows version...