從 Web 端程式碼呼叫原生端 WinRT 程式碼

您的 Web 端 JavaScript 程式碼可以存取原生端 WinRT 方法和屬性,並利用 wv2winrt 工具 (WebView2 WinRT JS 投影工具) 。 wv2winrt工具會為您的 JavaScript 程式碼產生所需的程式碼檔案,並可使用任何 WinRT API 的方法和屬性,包括:

  • WebView2 主應用程式的 WinRT API。
  • Windows WinRT API。
  • 協力廠商 WinRT API。

如需為何要讓 Web 端 JavaScript 程式碼存取 WinRT 主應用程式的方法和屬性的詳細資訊,請參閱 從 Web 端程式碼呼叫原生程式碼簡介。

為什麼 WinRT 和 .NET 使用不同的方法

本文適用于 WinRT WebView2 API,不適用於 .NET WebView2 API。 本文中的 C# 程式碼將會針對 .NET WebView2 API 建置,但不會執行。 使用 AddHostObjectToScript 本文的 .NET WebView2 API C# 程式碼呼叫 會產生錯誤訊息。

在投影 WinRT 物件時,需要 wv2winrt 工具 (WebView2 WinRT JS 投影工具) ,因為 WinRT 不支援 IDispatch 或任何其他機制可動態檢查 WinRT 物件並與之互動,WebView2 的 Win32 和 .NET 平臺支援此物件。 如需 .NET 的 AddHostObjectToScript 使用,請 參閱從 Web 端程式碼呼叫原生端程式碼 ,而不是本文。

WinUI 3 與 WinUI 2 的設定差異

如果您的 WinRT WebView2 應用程式以 WinUI 3 (Windows 應用程式 SDK) 為目標,而不是 WinUI 2 (UWP) ,以下是下方進一步提供的 WinUI 3 特定步驟概觀:

  • 在未封裝的應用程式中,您必須執行「使用Windows 執行階段元件增強非封裝桌面應用程式」一文中的其他步驟。

  • 將 新 WinRTAdapter 增至 CsWinRTIncludes

  • 針對 WinUI 3 (Windows 應用程式 SDK) 應用程式,主要應用程式專案具有 WinAppSDK 的參考,其中直接包含自己的 WebView2 SDK 檔案複本,因此您無法在未產生錯誤訊息的情況下,在主要應用程式專案中包含 WebView2 SDK 的參考。

  • 專案配接器版本不需要相符。

  • 安裝 Visual Studio 2022 Community 版本的「預設」選項之後,請在Visual Studio 安裝程式中按一下.NET卡片,然後在右側選取 [C# 範本Windows 應用程式 SDK核取方塊。

  • 如果正確的專案範本仍未出現:在Visual Studio 安裝程式中,按一下UWP卡片加以選取,選取右側的[v143 C++ 工具] 核取方塊,然後按一下 [修改] 按鈕。

此範例的策略和結束目標

策略

本文將逐步引導您完成下列主要步驟:

  1. (WebView2 WinRT JS 投影工具) ,建立wv2winrt工具的WinRTAdapter專案。

  2. 在此範例中,指定下列主機端 API 進行投影:

  3. 執行 wv2winrt 工具,為選取的命名空間或類別產生 C++/WinRT 原始程式碼。

  4. 在主要 WinUI 專案中呼叫 AddHostObjectToScript

  5. 從 Web 端 JavaScript 程式碼 (或 DevTools 主控台) 呼叫主機物件上的方法和屬性。

結束目標

首先,我們會挑選一些我們有興趣從 JavaScript 程式碼呼叫的 WinRT API。 在此範例中,我們將針對 Windows UWP 應用程式使用位於 命名空間中的 Windows.Globalization WinRT Language 類別。 Windows.Globalization.Language 類別可讓您從用戶端的原生 OS 取得語言資訊。

在 WebView2 主應用程式中,Web 端 JavaScript 程式碼接著可以存取原生端程式碼中物件上 Language 的方法和屬性。

透過 DevTools 主控台存取投影 API

在此範例逐步解說結尾,您將使用 Microsoft Edge DevTools 的 主控台 來測試讀取類別的 displayName 主機屬性 Language

const Windows = chrome.webview.hostObjects.sync.Windows;
(new Windows.Globalization.Language("en-US")).displayName;

DevTools 主控台接著會輸出 English (United States) 或其他語言顯示名稱,示範您已從 Web 端 JavaScript 程式碼呼叫原生端程式碼:

使用 DevTools 主控台測試從 Web 端程式碼呼叫原生端程式碼

您同樣可以存取 Windows.System.UserProfile 命名空間 成員。

透過原始程式碼檔案存取投影 API

同樣地,在原始程式碼檔案中,而不是 DevTools 主控台中,您可以存取投影主機物件。 首先,您要執行腳本的安裝程式碼:

// early in setup code:
const Windows = chrome.webview.hostObjects.sync.Windows;

然後在程式碼的主體中,將呼叫新增至投影物件,如下所示:

(new Windows.Globalization.Language("en-US")).displayName;

您同樣可以存取 Windows.System.UserProfile 命名空間 成員。

讓我們開始吧!

步驟 1:建立或取得基本的 WebView2 專案

安裝 Visual Studio

  • 如果尚未安裝 Visual Studio 2015 或更新版本,請在個別的視窗或索引標籤中,參閱在設定 WebView2 的開發環境安裝 Visual Studio。 遵循該節中的步驟,然後返回此頁面並繼續執行下列步驟。 本文顯示 Visual Studio Community 2022 版的螢幕擷取畫面。

安裝 Microsoft Edge 的預覽通道

  • 如果尚未在個別視窗或索引標籤中安裝 Microsoft Edge (Beta、Dev 或 Canary) 的預覽通道,請參閱在設定WebView2 的開發環境安裝 Microsoft Edge 的預覽通道。 遵循該節中的步驟,然後返回此頁面並繼續執行下列步驟。

建立或開啟基本 WebView2 專案

  1. 請執行下列任何方法來取得基準入門專案,其中包含內嵌 WebView2 控制項的幾行 WebView2 程式碼:

  2. 在本機磁片磁碟機上,開啟您在上面取得的 .sln 檔案,例如範例存放庫解決方案:

    • <your-repos-directory>/WebView2Samples-main/GettingStartedGuides/WinUI2_GettingStarted/MyUWPGetStartApp.sln
    • <your-repos-directory>/WebView2Samples/GettingStartedGuides/WinUI2_GettingStarted/MyUWPGetStartApp.sln

    範例解決方案會在 Visual Studio 中開啟:

    為 wv2winrt 工具新增專案

  3. 在 Visual Studio 中,選取 [偵錯>開始偵錯]。 這會建置專案,然後執行專案的基準版本。 基準應用程式隨即開啟,例如 MyUWPGetStartApp 視窗:

    WebView2 WinUI 2 UWP 範例視窗

    顯示的是已新增 WebView 控制項的 WinUI 2 (UWP) 應用程式,設定為一開始流覽至 Bing.com。 這是在 WinUI 2 中開始使用 WebView2 (UWP) 應用程式中執行步驟所產生的應用程式。

  4. 關閉應用程式視窗。

步驟 2:新增 wv2winrt 工具的 WinRTAdapter 專案

接下來,在 WebView2 WinRT JS 投影工具) (建立 wv2winrt工具的WinRTAdapter專案。 此專案會建置執行工具所產生的程式碼程式庫。 此產生的程式碼可讓 WinRT API 在 WebView2 控制項中公開。

新增 wv2winrt 工具的專案,如下所示:

  1. 在 Visual Studio 中,從上一個步驟開啟您的 WinUI 專案。

  2. 在方案總管中,以滑鼠右鍵按一下方案 (而不是專案) ,然後選取 [新增>專案]。 [ 新增專案] 對話方塊隨即開啟。

  3. 在 [搜尋]文字方塊中,輸入 Windows 執行階段 元件 (C++/WinRT)

    替代方法:如果您未依照下列編號步驟所述,使用Windows 執行階段 元件 (C++/WinRT) 的專案範本來新增專案,則必須依照UWP 應用程式 > C++/WinRT 簡介中的步驟,改為安裝通用 Windows 平臺開發工作負載。

  4. 取 Windows 執行階段 元件 (C++/WinRT) 卡片,然後按一下 [下一步]按鈕:

    在 [新增專案] 對話方塊中選取 Windows 執行階段 元件 (C++/WinRT) 卡片

    注意: 請確定範本的名稱中包含 「C++/WinRT」。 如果未列出此範本,請從Visual Studio 安裝程式內安裝通用 Windows 平臺開發工作負載。 如果您使用 Visual Studio 2019,但仍找不到範本,請從 Visual Studio > 擴充功能管理延伸模組安裝適用于 VS2019 的 >C++/WinRT 範本和視覺化檢視

    [ 設定您的新專案 ] 視窗隨即開啟。

設定和建立專案

  1. 在 [ 專案名稱 ] 文字方塊中,將專案命名為 Project,特別是 WinRTAdapter注意: 目前,您必須使用此特定專案名稱。

    在 [設定新專案] 視窗中,將專案命名為 'WinRTAdapter'

    上述螢幕擷取畫面中的路徑會反映複製範例存放庫的方法。

  2. 按一下 [ 建立] 按鈕。

    [ 新增 Windows 專案] 對話方塊隨即開啟:

    [新增 Windows 專案] 對話方塊

  3. 按一下 [ 確定] 按鈕。

    WinRTAdapter專案隨即建立,並新增至主要專案旁方案總管:

    新建立的 WinRTAdapter 專案

  4. 取 [檔案全部儲存> (Ctrl+Shift+S) 。

webView2 WinRT JS 投影工具 (wv2winrt 工具) 會在此 WinRTAdapter 專案中執行。 在下列步驟中,您將針對此專案中選取的類別產生程式碼。

步驟 3:安裝適用于 WinRTAdapter 專案的 Windows 實作程式庫

在 WinRTAdapter 專案中,安裝 Windows 實作程式庫 (WIL) ,如下所示:

  1. 方案總管中,以滑鼠右鍵按一下WinRTAdapter專案,然後選取 [管理 NuGet 套件][NuGet 套件管理員]視窗會在 Visual Studio 中開啟。

  2. [NuGet 套件管理員] 視窗中,按一下 [ 流覽] 索引卷 標。

  3. [NuGet 套件管理員] 視窗的 [ 搜尋 ] 方塊中,輸入 Windows 實作程式庫,然後選取 [Windows 實作程式庫 ] 卡片:

    NuGet 套件管理員,選取 [Windows 實作程式庫] 套件

  4. 按一下 [ 安裝] 按鈕。 [ 預覽變更 ] 對話方塊隨即開啟:

    WinRTAdapter 專案的 [預覽變更] 對話方塊

  5. 按一下 [ 確定] 按鈕。

  6. 取 [檔案全部儲存> (Ctrl+Shift+S) 。

現在已針對 WinRTAdapter 專案安裝 WIL。 WINDOWS 實作程式庫 (WIL) 是僅限標頭的 C++ 程式庫,可讓您更輕鬆地使用適用于 Windows 的 COM 編碼。 它提供適用于 Windows COM 編碼模式的可讀取型別安全 C++ 介面。

步驟 4:安裝適用于 WinRTAdapter 專案的 WebView2 發行前版本 SDK

在 WinRTAdapter 專案中,也安裝 WebView2 SDK 的發行前版本,如下所示:

  1. 在方案總管中,以滑鼠右鍵按一下WinRTAdapter專案,然後選取 [管理 NuGet 套件]。 [NuGet 套件管理員] 視窗隨即開啟。

  2. [NuGet 套件管理員] 視窗中,按一下 [ 流覽] 索引卷 標。

  3. 選取 [ 包含發行前版本] 複 選框。

  4. 在 [ 搜尋] 方 塊中,輸入 WebView2

  5. 按一下 Microsoft.Web.WebView2 卡片。 詳細資訊會出現在視窗的中間區域。

  6. 在 [ 版本] 下拉式清單中,選取 WebView2 SDK 的 發行前 版本,或確定已選取 [最新發行前版本 ]。 版本必須是 1.0.1243.0 或更高版本。 請注意您選取的版本號碼。

    NuGet 套件管理員,選取 WinRTAdapter 專案的 WebView2 SDK 套件

  7. 按一下 [ 安裝] 按鈕。 [ 預覽變更 ] 對話方塊隨即開啟:

    將 WebView2 SDK 新增至 WinRTAdapter 專案的 [預覽變更] 對話方塊

  8. 按一下 [ 確定] 按鈕。

  9. 取 [檔案全部儲存> (Ctrl+Shift+S) 。

現在已針對 WinRTAdapter 專案安裝 WebView2 發行前版本 SDK。

步驟 5:僅在 WinUI 2 (安裝 WebView2 發行前版本 SDK)

在主要專案中,例如 MyUWPGetStartApp,安裝與您為 WinRTAdapter 專案安裝的相同 WebView2 SDK 發行前版本,如下所示:

  1. 在方案總管中,以滑鼠右鍵按一下主要專案,例如MyUWPGetStartApp,然後選取 [管理 NuGet 套件]。 [NuGet 套件管理員] 視窗隨即開啟。

  2. 選取 [ 包含發行前版本] 複 選框。

  3. 選取 [ 流覽] 索引卷 標。

  4. 在 [ 搜尋] 方 塊中,輸入 WebView2

  5. 按一下 Microsoft.Web.WebView2 卡片。 詳細資訊會出現在視窗的中間區域。

  6. 在 [ 版本] 下拉式清單中,選取 WebView2 SDK 的 發行前 版本,或確定已選取 [最新發行前版本 ]。 請務必使用 與 WinRTAdapter 專案所使用的相同版本;針對以 WinUI 2 (UWP) 為目標的 WinRT WebView2 應用程式,這必須與 WinRTAdapter 專案版本相同。 版本必須是 1.0.1243.0 或更高版本。

  7. 按一下 [ 安裝] 按鈕。 [預覽變更] 對話方塊隨即開啟,將 WebView2 新增至主要專案。

  8. 按一下 [ 確定] 按鈕。

    Visual Studio 看起來應該類似上述的步驟區段,不同之處在于現在 ,NuGet 套 件管理員已針對主要專案而非 WinRTAdapter 專案開啟。

  9. 取 [檔案全部儲存> (Ctrl+Shift+S) 。

現在已針對主要專案安裝 WebView2 發行前版本 SDK。

步驟 6:為選取的主機 API 產生原始程式碼

接下來,在 WebView2 WinRT JS 投影工具) (設定 wv2winrt 工具,以納入您想要使用的 WinRT 類別。 這會產生將接著編譯的原始程式檔。 產生這些 API 的程式碼可讓您的 Web 端 JavaScript 程式碼呼叫這些 API。

在下列範例步驟中,我們將指定兩 Windows 個命名空間, 而 wv2winrt 工具只會針對這些命名空間下的 API 產生原始程式碼:

稍後,當範例應用程式執行時,您會從 DevTools 主控台呼叫這些 API,以示範可以從 Web 端程式碼呼叫這些指定的主機端 API。

指定命名空間和類別,如下所示:

  1. 在方案總管中,以滑鼠右鍵按一下WinRTAdapter專案,然後選取 [屬性][WinRTAdapter 屬性頁] 對話方塊隨即開啟。

  2. 在左側展開並選取 [通用屬性>WebView2]

  3. [使用 WebView2 WinRT API] 設定為 [否]。 如此一來,WebView2 SDK 就不會將 WebView2 WinRT 元件複製到專案的輸出。 此 WinRTAdapter 專案不會呼叫任何 WebView2 WinRT API,因此不需要 WinRT 元件。

  4. [使用 wv2winrt 工具 ] 設定為 [ 是]

  5. [使用 JavaScript 案例] 設定為 [是]

  6. 在 [ 包含篩選] 資料列中 ,按一下右邊的資料行,按一下該儲存格中的下拉式功能表,然後按一下 [ 編輯]。 [ 包含篩選] 對話方塊隨即開啟。

  7. 在最上方的文字方塊中,將下列字串貼到個別的行上,而不會有前置或尾端空白字元:

    Windows.System.UserProfile
    Windows.Globalization.Language
    

    [包含篩選] 對話方塊

    您必須指定命名空間或類別的完整名稱,如上所示。

  8. 按一下 [ 確定] 按鈕以關閉 [ 包含篩選] 對話方塊。

  9. 針對本逐步解說,請確定 [WinRTAdapter 屬性頁 ] 對話方塊如下所示:

    已展開 [通用屬性 > WebView2] 的 [WinRTAdapter 屬性頁] 對話方塊

  10. 按一下 [ 確定] 按鈕以關閉 [ 屬性頁 ] 對話方塊。

  11. 取 [檔案全部儲存> (Ctrl+Shift+S) 。

新增指向配接器專案的參考

接下來,在主要專案中新增參考,指向配接器專案。

在主要專案中,例如 MyUWPGetStartApp,新增指向 WinRTAdapter 專案的參考,如下所示:

  1. 在方案總管中,展開主要專案,例如MyUWPGetStartApp,以滑鼠右鍵按一下 [參考],然後選取 [新增參考]。 [ 參考管理員 ] 對話方塊隨即開啟。

  2. 在左側樹狀結構中,選取 [ 專案]。 選取 [WinRTAdapter] 複 選框:

    主要專案 [參考管理員] 對話方塊中的 WinRTAdapter 核取方塊

  3. 按一下 [ 確定] 按鈕以關閉 [ 參考管理員 ] 對話方塊。

  4. 取 [檔案全部儲存> (Ctrl+Shift+S) 。

產生 API 程式碼

接下來,產生 API 程式碼:

  1. 以滑鼠右鍵按一下 WinRTAdapter 專案,然後選取 [ 建置]

    針對您在 WebView2 WinRT JS 投影工具 (wv2winrt工具的 [包含篩選] 對話方塊中指定的命名空間或類別,會產生原始程式碼) :

    • Windows.System.UserProfile 命名 空間
    • Windows.Globalization.Language
  2. 建置完成之後,選取[檔案全部儲存> (Ctrl+Shift+S) 。

重要事項

如果您已安裝 WebView2 SDK 的發行版本,而您的組建失敗 error MIDL2011: [msg]unresolved type declaration [context]: Microsoft.Web.WebView2.Core.ICoreWebView2DispatchAdapter [ RuntimeClass 'WinRTAdapter.DispatchAdapter' ] ,則這是 WebView2 SDK 發行版本中的問題,您必須在上述步驟中將 [使用 WebView2 WinRT API ] 變更為 [是 ]。

或者,在專案檔中的最後一個 </ItemGroup> 後面新增下列專案 WinRTAdapter.vcxproj

<ItemGroup Condition="'$(WebView2UseDispatchAdapter)' == 'true'">
 <Reference Include="$(WebView2SDKPath)lib\Microsoft.Web.WebView2.Core.winmd">
   <!-- wv2winrt needs Dispatch Adapter metadata to generate code -->
 </Reference>
</ItemGroup>

將 取代為 WebView2 SDK 安裝所在的目錄, \ 並以 結尾的 取代 $(WebView2SDKPath) 。 例如:..\<sample-directory>\packages\Microsoft.Web.WebView2.1.0.1264.42\

步驟 7:僅) 更新目標 Framework (WinUI 3

如果您的應用程式適用于 WinUI 2 (UWP) ,請略過此步驟。

步驟 8:在主要專案中新增主機物件

接下來,將 WinRT 物件從主應用程式的原生端傳遞至主應用程式的 Web 端。 若要這樣做,請新增 InitializeWebView2Async 呼叫 AddHostObjectToScript 的方法,如下所示:

  1. 在方案總管中,展開主要專案,例如MyUWPGetStartApp、展開MainPage.xaml,然後選取MainPage.xaml.cs

  2. MainPage 建構函式下方,新增下列 InitializeWebView2Async 方法:

    private async void InitializeWebView2Async()
    {
       await WebView2.EnsureCoreWebView2Async();
       var dispatchAdapter = new WinRTAdapter.DispatchAdapter();
       WebView2.CoreWebView2.AddHostObjectToScript("Windows", dispatchAdapter.WrapNamedObject("Windows", dispatchAdapter));
    }
    

    這個方法會呼叫 AddHostObjectToScript

    在 行中 AddHostObjectToScript("Windows", ...Windows 是最上層命名空間。 如果您有其他最上層命名空間,您可以將其他呼叫新增至 AddHostObjectToScript ,如下列範例所示:

    WebView2.CoreWebView2.AddHostObjectToScript("RuntimeComponent1", dispatchAdapter.WrapNamedObject("RuntimeComponent1", dispatchAdapter));
    

    呼叫 WrapNamedObject 會建立命名空間的 RuntimeComponent1 包裝函式物件。 呼叫會 AddHostObjectToScript 使用名稱 RuntimeComponent1 將包裝的物件加入腳本。

    如需如何使用自訂 WinRT 元件的完整指引,請參閱下方 的自訂 (協力廠商) WinRT 元件

  3. 在建構函式的 MainPage 下方 this.InitializeComponent(); ,新增下列程式碼:

    InitializeWebView2Async();
    
  4. 以滑鼠右鍵按一下主要專案,例如 MyUWPGetStartApp,然後選 取 [設定為啟始專案]。 粗體表示啟動專案。

  5. 取 [檔案全部儲存> (Ctrl+Shift+S) 。

  6. F5 執行範例應用程式。 已啟用 WebView2 的 WinUI 2 (UWP) 應用程式隨即開啟:

    WebView2 WinUI 2 UWP 應用程式

主應用程式的 Web 端程式碼 (和 DevTools 主控台) 現在可以呼叫指定之命名空間或主機物件類別的方法和屬性。

步驟 9:從 Web 端 JavaScript 呼叫主機物件上的方法和屬性

透過 DevTools 主控台存取投影 API

接下來,使用 DevTools 主控台示範 Web 端程式碼可以呼叫 wv2winrt 工具中指定的主機端 API, (WebView2 WinRT JS 投影工具) :

  1. 如果應用程式未執行,請在 Visual Studio 中按 F5 執行範例應用程式。

  2. 按一下 [WebView2 範例應用程式] 視窗的主部分以提供焦點,然後按 Ctrl+Shift+I 開啟 Microsoft Edge DevTools。 或者,以滑鼠右鍵按一下頁面,然後選取 [ 檢查]

    Microsoft Edge DevTools 視窗隨即開啟。

  3. 如果未顯示 Microsoft Edge DevTools 視窗,請按 Alt+Tab 來顯示它。

  4. [DevTools] 視窗中 ,選取 [ 主控台] 索引 標籤。

  5. 按一下 [清除主控台 (清除主控台圖示) ] 按鈕,或在 主控台 中按一下滑鼠右鍵,然後選取 [清除主控台]。 訊息可能會定期出現在主控台中。

  6. 在 DevTools 主控台中,貼上下列 Windows.Globalization.Language Class 程式碼,然後按 Enter

    const Windows = chrome.webview.hostObjects.sync.Windows;
    (new Windows.Globalization.Language("en-US")).displayName;
    

    主控台會輸出語言名稱字串,例如 English (United States) ,示範您可以從 Web 端 JavaScript 程式碼呼叫應用程式的主機端 (原生端) 程式碼:

    使用 DevTools 主控台測試從 Web 端程式碼呼叫原生端程式碼

  7. 請嘗試省略括弧。 在 DevTools 主控台中,輸入下列語句:

    new Windows.Globalization.Language("en-US").displayName;
    

    主控台會輸出語言名稱字串,例如 English (United States)

    您同樣可以存取 Windows.System.UserProfile 命名空間 成員。

  8. 關閉 DevTools 視窗。

  9. 關閉應用程式。

恭喜您! 您已完成從 JavaScript 程式碼呼叫 WinRT 程式碼的範例示範。

透過原始程式碼檔案存取投影 API

在上面,我們使用 DevTools 主控台來執行 JavaScript 語句,以存取投影的主機物件。 同樣地,您可以從原始程式碼檔案記憶體取投影主機物件。 若要這樣做,請先執行腳本的安裝程式碼:

// early in setup code:
const Windows = chrome.webview.hostObjects.sync.Windows;

然後在程式碼的主體中,將呼叫新增至投影物件,如下所示:

(new Windows.Globalization.Language("en-US")).displayName;

您同樣可以存取 Windows.System.UserProfile API 成員。

這是教學課程步驟的結尾。 下列各節是 WebView2 WinRT 應用程式的一般資訊。

自訂 (協力廠商) WinRT 元件

webView2 WinRT JS 投影工具 (wv2winrt 工具) 支援自訂的協力廠商 WinRT 元件,以及第一方 OS WinRT API。

使用 wv2winrt 工具的協力廠商 WinRT 元件

若要使用自訂 (協力廠商) WinRT 元件搭配 wv2winrt 工具,除了上述步驟之外,也請執行下列步驟:

  1. 將主要應用程式以外的第三個專案 (和 WinRTAdapter 專案) 新增至實作 WinRT 類別的 Visual Studio 方案。

  2. 讓 WinRTAdapter 專案「新增參考」到包含 WinRT 類別的新第三個專案。

  3. 在屬性中更新 WinRTAdapter 專案的 Include 篩選準則,以同時包含您的新類別。

  4. 在 中新增一行 InitializeWebView2Async ,以新增 winrt 類別的命名空間:

    WebView2.CoreWebView2.AddHostObjectToScript("MyCustomNamespace", dispatchAdapter.WrapNamedObject("MyCustomNamespace", dispatchAdapter));

  5. 若要輕鬆地從 Web 呼叫方法,請選擇性地將命名空間同步 Proxy 新增為腳本中的全域物件。 例如:

    window.MyCustomNamespace = chrome.webview.hostObjects.sync.MyCustomNamespace;

如需此範例,請參閱下列 WebView2 範例:

非同步 WinRT 方法

遵循上述指南中的步驟,您應該能夠使用同步 Proxy。 針對非同步方法呼叫,您必須使用 chrome.webview.hostObjects.options.forceAsyncMethodMatches

屬性 forceAsyncMethodMatches 是 RegExes 的陣列,其中,如果任何 RegEx 符合同步 Proxy 上的方法名稱,則會改為以非同步方式執行方法。 將這個 設定為 [/Async$/] 會使其符合以 後置詞 Async 結尾的任何方法。 然後比對方法呼叫的運作方式就如同非同步 Proxy 上的方法,並傳回您可以等候的承諾。

例如:

const Windows = chrome.webview.hostObjects.sync.Windows;
chrome.webview.hostObjects.options.forceAsyncMethodMatches = [/Async$/];

let result = await Windows.System.Launcher.launchUriAsync(new Windows.Foundation.Uri('https://contoso.com/'));

如需詳細資訊,請參 forceAsyncMethodMatchesCoreWebView2.AddHostObjectToScript 方法中的資料列。

訂閱 WinRT 事件

WinRT 事件也會透過腳本 Proxy 公開。 您可以使用 addEventListener(string eventName, function handler)removeEventListener(string eventName, function handler) 和 方法,新增和移除實例 WinRT 事件和靜態 WinRT 事件的事件處理常式。

這些方法的運作方式類似于相同名稱的 DOM 方法。 使用您想要訂閱做為第一個參數之 WinRT 事件的字串名稱進行呼叫 addEventListener ,並在每次引發事件時呼叫函式回呼。 使用相同的參數呼叫 removeEventListener 會取消訂閱該事件。 例如:

const Windows = chrome.webview.hostObjects.sync.Windows;
const coreApplication = Windows.ApplicationModel.Core.CoreApplication;
const coreApplicationView = coreApplication.getCurrentView();
const titleBar = coreApplicationView.titleBar;
titleBar.addEventListener('IsVisibleChanged', () => {
    console.log('titlebar visibility changed to: ' + titleBar.isVisible);
});

針對提供事件引數的 WinRT 事件,這些會作為事件處理常式函式的第一個參數提供。 例如,事件 Windows.Foundation.Collections.PropertySet.MapChanged 具有 IMapChangedEventArgs<string, object> 事件引數物件,而該物件會作為回呼的參數提供。

const Windows = chrome.webview.hostObjects.sync.Windows;
const propertySet = new Windows.Foundation.Collections.PropertySet();
propertySet.addEventListener('MapChanged', eventArgs => {
    const key = eventArgs.key;
    const collectionChange = eventArgs.collectionChange;
    // ...
});

event args 物件另外會有下列屬性:

內容名稱 說明
target 引發事件的物件
type 事件的字串名稱
detail 提供給 WinRT 委派之所有參數的陣列

讓 AddHostObjectToScript JavaScript Proxy 的行為更像其他 JavaScript API

AddHostObjectToScript 預設為使用非同步和詳細資訊 Proxy,但您可以讓 AddHostObjectToScript JavaScript Proxy 的運作方式更像其他 JavaScript API。 若要 AddHostObjectToScript 深入瞭解 及其預設行為,請參閱 AddHostObjectToScript。 此外,如果您要從 JavaScript UWP 應用程式中的 JavaScript WinRT 投影,或從以 EdgeHTML 為基礎的 WebView 移轉主應用程式,您可能想要使用下列方法,以更符合先前的行為。

若要讓 AddHostObjectToScript JavaScript Proxy 更像其他 JavaScript API,請設定下列屬性:

  • chrome.webview.hostObjects.option.defaultSyncProxy - Proxy 可以是非同步或同步的。 一般而言,我們知道在同步 Proxy 上呼叫方法時,結果也應該是同步 Proxy。 但在某些情況下,我們會遺失該內容,例如將函式的參考提供給原生程式碼,然後在稍後呼叫該函式時提供原生程式碼。 在這些情況下,除非設定此屬性,否則 Proxy 會是非同步。

  • chrome.webview.hostObjects.options.forceAsyncMethodMatches - 這是正則運算式的陣列。 如果您在同步 Proxy 上呼叫方法,如果方法名稱符合此陣列中的字串或正則運算式,則會以非同步方式執行方法呼叫。 將此值設定為 [/Async$/] 會讓任何以 為結尾 Async 的方法成為非同步方法呼叫。 如果非同步方法在這裡不相符,而且未強制為非同步,則會以同步方式叫用方法,封鎖呼叫 JavaScript 的執行,然後傳回承諾的解析,而不是傳回承諾。

  • chrome.webview.hostObjects.options.ignoreMemberNotFoundError - 如果您嘗試取得 Proxy 的屬性值,而且屬性不存在於對應的原生類別上,您會收到例外狀況 - 除非您將此屬性設定為 true ,在此情況下,行為會比對 Chakra WinRT 投影行為 (和一般 JavaScript 行為) 並傳回 undefined ,且不會發生錯誤。

Chakra WinRT 投影會將 WinRT 命名空間直接放在根物件上。 相反地:

  • AddHostObjectToScript 將非同步根 Proxy 放在 上 chrome.webview.hostObjects
  • AddHostObjectToScript 將同步根 Proxy 放在 上 chrome.webview.hostObjects.sync

若要存取 Chakra WinRT 投影程式碼預期的根 Proxy,您可以將根 Proxy WinRT 命名空間位置指派給根物件。 例如:

window.Windows = chrome.webview.hostObjects.sync.Windows;

若要確保設定這一切的 JavaScript 會在任何其他專案之前執行,您可以將上述語句新增至您的 JavaScript,或者您可以使用 CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync 方法,在執行任何其他腳本之前,告知 WebView2 為您插入上述語句。

下列範例示範上述技術:

webview.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(
            "(() => {" +
                    "if (chrome && chrome.webview) {" +
                        "console.log('Setting up WinRT projection options');" +
                        "chrome.webview.hostObjects.options.defaultSyncProxy = true;" +
                        "chrome.webview.hostObjects.options.forceAsyncMethodMatches = [/Async$/,/AsyncWithSpeller$/];" +
                        "chrome.webview.hostObjects.options.ignoreMemberNotFoundError = true;"  +
                        "window.Windows = chrome.webview.hostObjects.sync.Windows;" +
                    "}" +
                "})();");

取得 WebView2 屬性的相關資訊

WebView2 屬性的相關資訊可在兩個位置取得:

  • WinRTAdapter 專案的屬性頁。
  • wv2winrt.exe 命令列說明。 這是 WebView2 WinRT JS 投影工具) (wv2winrt 工具。

WinRTAdapter 專案的屬性頁

在 WinRTAdapter 專案的 [屬性頁] 中,如需屬性的說明,請按一下屬性資料列。 說明會顯示在對話方塊的底部:

WinRTAdapter 屬性頁中列出的屬性

wv2winrt.exe 屬性的命令列說明

的命令列說明 wv2winrt.exe 會提供 webView2 WinRT JS 投影工具) (wv2winrt 工具參數的相關資訊。 例如:

參數 說明
verbose 列出一些要標準顯示的內容,包括已建立的檔案,以及包含和排除規則的相關資訊。
include 上述清單預設會排除命名空間和執行時間類別,但列出的除外。 include 宣告可以是包含該命名空間中所有專案的命名空間,或是只包含該 Runtimeclass 的 Runtimeclass 名稱。
use-javascript-case 變更產生的程式碼,以產生與 Chakra JavaScript WinRT 投影使用相同大小寫樣式的方法名稱、屬性名稱等等。 預設值是產生符合 winrt 的名稱。
output-path 設定將寫入所產生檔案的路徑。
output-namespace 設定要用於所產生 WinRT 類別的命名空間。
winmd-paths 以空格分隔的清單,列出所有應該檢查以產生程式碼的 winmd 檔案。

另請參閱

教學課程和範例:

API 參考:

.NET 對等文章: