WebView2是微软将Chromium包装起来,提供给应用使用的web组件。

由于webView32要在Win32/COM、.NET、WinRT等应用程序中工作,基本上WebView2提供的接口都是基于COM的,这样不仅语言无关,而且互操作性最高。

本文中要介绍的的是CoreWebView2这个WebView2核心对象的AddHostObjectToScript方法。此方法对于Win32/COM、.NET、WinRT的接口中均存在,文档如下:

简单起见,本文的目标场景是C#/WinRT,也就是使用WinRT中的CoreWebView2.AddHostObjectToScript接口。

相关代码

C#代码来自于WebView2 WinRT CoreWebView2.AddHostObjectToScript

发现无法通过AddHostObjectToScript注入COM对象, AddHostObjectToScript fails on WebView2 (WinUI 3) #2015 给出的方法是

// Originally was
// MyWebView.CoreWebView2.AddHostObjectToScript("bridge", new Bridge());
var core = MyWebView.CoreWebView2;
var interop = (ICoreWebView2Interop)(object)core;
interop.AddHostObjectToScript("bridge", new Bridge());

Visual Studio显示无法找到ICoreWebView2Interop。看了文档interface ICoreWebView2Interop也没有相关线索。

但是在Github上发现了WebView2BasicPage.xaml.cs,于是有了下面的定义:

[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("912b34a7-d10b-49c4-af18-7cb7e604e01a")]
public interface ICoreWebView2Interop
{
  // IDL: HRESULT AddHostObjectToScript([in] LPCWSTR name, [in] VARIANT* object);
  void AddHostObjectToScript([In] string name, [In] ref object obj);
}

结果是:System.InvalidCastException: 'Invalid cast from 'Microsoft.Web.WebView2.Core.CoreWebView2' to 'ICoreWebView2Interop'.',依然不行。

从这个Issue AccessViolation 0xC0000005 was thrown while calling AddHostObjectToScript #4377 看来WinRT版的WebView2目前还是有比较多的问题的。这个问题在WebView2的问题单是 AddHostObjectToScript gives an AccessViolationException when called on a winrt object #2144 。最早提出使用的,应该是 WebView2 AddHostObjectToScript Not Implemented Error #958

怀疑是WindowsAppSdk中带的WebView2有问题,但是通过NuGet安装Microsoft.Web.WebView2却又遇到 windowsappsdk and webview2 pre-reease #1921 中描述的问题。即:

C:\Users\mathe\source\repos\TestWV2\TestWV2\TestWV2\MainWindow.xaml.cs(31,82,31,94): error CS0433: The type 'CoreWebView2' exists in both 'Microsoft.Web.WebView2.Core, Version=1.0.1056.0, Culture=neutral, PublicKeyToken=2a8ab48044d2601e' and 'Microsoft.WinUI, Version=3.0.0.0, Culture=neutral, PublicKeyToken=de31ebe4ad15742b'

同样的问题也报告在 Can’t build any xaml islands app with 2.7.0-prerelease.210827001 #1716 ,又有 Can’t build any xaml islands app with 2.7.0-prerelease.210827001 #5793

通过这个办法https://github.com/microsoft/microsoft-ui-xaml/issues/5689#issuecomment-982128778,至少可以编译了,可是之前的那个System.InvalidCastException又出现了。

关于.NET装配件冲突的问题,可以学习Type exists in 2 assemblies

查看[ Accessing a function with parameter that is added using AddHostObjectToScript returns “Parameter is incorrect.” #1789 ])(https://github.com/MicrosoftEdge/WebView2Feedback/issues/1789)

https://github.com/microsoft/microsoft-ui-xaml/issues/1967#issuecomment-893621478

WebView2不支持ms-appx-web:///ms-appx-data:///了,参考https://github.com/MicrosoftEdge/WebView2Feedback/issues/37

可以使用 SetVirtualHostNameToFolderMapping:

    await myWebview.EnsureCoreWebView2Async(); // ensure the CoreWebView2 is created
    var core_wv2 = myWebview.CoreWebView2;
    if (core_wv2 != null)
    {
        core_wv2.SetVirtualHostNameToFolderMapping(
            "appassets.example", "assets",
            Microsoft.Web.WebView2.Core.CoreWebView2HostResourceAccessKind.Allow);

        myWebview.Source = new Uri(https://appassets.example/myVideo.mp4);
    }

也不支持直接从resources.pri 加载,或许可以用CoreWebView2.WebResourceRequested达到间接加载。

其他参考

(完)