[WebView2] ScriptからHostObjectを呼び出す / How to call HostObject from Script

Microsoft Edge WebView2 を利用し、Windowsアプリの組み込みWebViewで表示したページ内ScriptからHostObjectを利用する方法です。
.NET 組み込みの [WebBrowser.ObjectForScripting](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.controls.webbrowser.objectforscripting?view=windowsdesktop-6.0)の代替です。
This is a method of using HostObject from a script in the built-in WebView of a Windows app using Microsoft Edge WebView2.
An alternative to the .NET built-in [WebBrowser.ObjectForScripting](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.controls.webbrowser.objectforscripting?view=windowsdesktop-6.0).

サンプルは、C#, TypeScript(JavaScript)です。
This sample is C# and TypeScript(JavaScript). 

参考/Reference：[CoreWebView2.AddHostObjectToScript(String, Object) Method](https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.web.webview2.core.corewebview2.addhostobjecttoscript?view=webview2-dotnet-1.0.705.50#Microsoft_Web_WebView2_Core_CoreWebView2_AddHostObjectToScript_System_String_System_Object_)

### Windows アプリ側 / Windows app side

#### HostObjectをCOMで利用可能にする / Make HostObject available in COM

##### アセンブリーをInProc COMサーバーで利用可能にする / Make assemblies available on InProc COM servers

```Csharp:AssemblyInfo.cs
[assembly: ComVisible(true)]
[assembly: Guid("GUIDSTRING")]
```

##### HostObjectに登録するクラスを定義する / Define classes to register with HostObject

```Csharp:HostObject.cs
namespace App
{
    [ComVisible(true)]
    [Guid("GUIDSTRING")]
    public class HostObject
    {
        public string GetString()
        {
            return "Success!
        }
    }
}
```

#### WebView2コントロールにHostObjectを登録する / Register HostObject in a WebView2 control

```Csharp:MainWindow.xaml.cs
namespace App
{
    public partial class MainWindow : Window
    {
        ...
        private void WebBrowserControl_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs eventArgs)
        {
            this.WebBrowserControl.CoreWebView2.AddHostObjectToScript("myHostObject", new HostObject());
        }
        ...
    }
}

```

### Web アプリ側 (TypeScript) / Web App Side (TypeScript)

#### Chromeタイプを追加する / Add Chrome type

バージョンは任意です
Version is optional

```json:package.json
{
  "devDependencies": {
    "@types/chrome": "^0.0.132"
  }
}
```

#### WebView2 ページ内スクリプトで、HostObjectを呼び出す / Call HostObject in the WebView2 in-page script

```TypeScript:home.ts
/// <reference path=".\node_modules\@types\chrome\index.d.ts"/>

// chromeにwebviewを追加する / Add webview to chrome

declare namespace chrome {
    export var webview: WebView;
}

// webviewにhostObjectsを追加する / Add hostObjects to webview
interface WebView {
    hostObjects: HostObjects;
}

interface HostObjects {
    myHostObject: MyHostObject;
    sync: SyncProxy; // 同期プロキシ / sync proxy
}

interface SyncProxy {
    myHostObject: MyHostObject;
}

interface MyHostObject {
    GetString(): string;
}

// 同期function / sync function
function invokeHostObjects() {
    var result = chrome.webview.hostObjects.sync.myHostObject.GetString();
    ...
}

// 非同期function / async function
async function asyncInvokeHostObjects() {
    var result = await chrome.webview.hostObjects.myHostObject.GetString();
    ...
}

invokeHostObjects();
asyncInvokeHostObjects();
```