Search code examples
c#exceptionuwpwebview2

CoreWebView2.AddHostObjectToScript throws System.Exception


CoreWebView2.AddHostObjectToScript throws System.Exception: 'The group or resource is not in the correct state to perform the requested operation.' Version SDK: 1.0.1245.22 latest stable - (and Microsoft.UI.Xaml 2.8.0-prerelease.210927001) Runtime: Framework: UWP OS: Windows 11, build 22000

Reproduce Steps

  1. Create an UWP project
  2. Add necessary nuget packages (Microsoft.Web.Webview2 latest stable release and Microsoft.UI.Xaml 2.8.0-prerelease)
  3. Add WebView2 component to MainPage.xaml
  4. Create HostObject class with necessary tags
  5. Add code for navigation starting or navigation completed method in WebView2 (MainPage.xaml.cs)
  6. Ensure CoreWebView2 is not null by calling myWebView.EnsureCoreWebView2Async(); inside method
  7. Try use myWebView.CoreWebView2.AddHostObjectToScript("HostObject", hostObject); inside method (Also tried to make a new project uwp (as Windows Runtime Component) and create the HostObject class there but still same exception. In addition tried to change tags on HostObject class but still same issue)

Example of HostObject class:

[AllowForWeb]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class JsCallbacksUwp
{
    public JsCallbacksUwp()
    {

    }
}

Example code for Navigation Completed that throws the exception:

private async void WebView2_NavigationCompleted(WebView2 sender, CoreWebView2NavigationCompletedEventArgs args)
{
    await sender.EnsureCoreWebView2Async();    
    var browserHostObject = new JSCallbacksUwp();    
    sender.CoreWebView2.AddHostObjectToScript("HostObject", browserHostObject);
}

Exception Thrown Image


Solution

  • I got my answer from github's community at WebView2 Feedback.

    Firstly i followed the guide that Syul968 showed me there which was:

    The WinRT CoreWebView2 class (the one used by WinUI) tries to automatically create a "wrapper" when this is the case, but it needs a DispatchAdapter instance to be set through CoreWebView2Settings.HostObjectDispatchAdapter. We have also been working on this feature lately. Our latest pre-release package (1.0.1248-prerelease) includes a tool, wv2winrt, to help project new and existing WinRT components: Call native-side WinRT code from web-side code

    Secondly i followed the steps from david-risney answer:

    Our current documentation only shows you how to do it for OS provided WinRT APIs and not for your own WinRT APIs. We need to fix this. Until then I would recommend following the existing directions from Call native-side WinRT code from web-side code, and then additionally doing the following:

    1. Add a third project to your VS solution that implements your winrt class.
    2. Have the WinRTAdapter project 'Add a reference' to your new third project containing your winrt class.
    3. Update the WinRTAdapter project's Include filter to also include your new class.
    4. Add an additional line to InitializeWebView2Async to add your winrt class's namespace WebView2.CoreWebView2.AddHostObjectToScript("MyCustomNamespace", dispatchAdapter.WrapNamedObject("MyCustomNamespace", dispatchAdapter));
    5. And optionally add your namespace sync proxy as a global object in script window.MyCustomNamespace = chrome.webview.hostObjects.sync.MyCustomNamespace; You should then be able to use your type via script.

    Lastly you can check my changes to my example.