访问底层 CoreWebView2 COM 的完整功能
API。在初始化完成之前返回 null。见
WebView2 class 用于初始化概述的文档。
目前尚不清楚您如何初始化 CoreWebView2。问题可能与您的 CoreWebView2 初始化和执行顺序有关。您可以使用Debug.WriteLine 来确认这一点。为了帮助调试问题,请订阅以下事件:
WebView2 事件:
CoreWebView2 事件:
下面显示了如何为显式和隐式初始化设置 UserDataFolder。
创建 Windows 窗体应用程序 (.NET Framework)
下载/安装 NuGet 包:Microsoft.Web.WebView2 (v 1.0.1293.44)
笔记:WebView2 版本1.0.1343.22 似乎有一个导致空引用异常的错误。这可以通过在 CoreWebView2InitializationCompleted 事件处理程序中放置以下代码来看到:
Private Sub WebView21_CoreWebView2InitializationCompleted(sender As Object, e As CoreWebView2InitializationCompletedEventArgs) Handles WebView21.CoreWebView2InitializationCompleted
Dim wv As WebView2 = DirectCast(sender, WebView2)
Debug.WriteLine($"UserDataFolder: {wv.CoreWebView2.Environment.UserDataFolder}")
Debug.WriteLine($"Edge Browser version: {wv.CoreWebView2.Environment.BrowserVersionString}")
End Sub
但是,使用如下所示的 CoreWebView2Environment 显式初始化似乎在 WebView2 版本1.0.1343.22 中工作。
在表单上,我使用了 TableLayoutPanel、TextBox(名称:textBoxAddressBar)、Button(名称:btnBack、btnForward、btnGo)和 WebView2(名称:WebView21)控件。
这是表单的样子:
在下面的代码中,每个选项都包含一些通用代码。为了避免混淆,我在代码中包含了完整的代码(对于每个选项)并添加了解释(作为 cmets)。下面的每个选项都已经过测试。
选项1- 显式初始化(CoreWebView2Environment)
Imports System.IO
Imports Microsoft.Web.WebView2.Core
Imports Microsoft.Web.WebView2.WinForms
Public Class Form1
Private Async Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
LogMsg($"WebView2 version: {GetWebView2Version()}")
'explicitly initialize CoreWebView2
Await InitializeCoreWebView2Async(WebView21)
'since we've used explicit initialization, which is Awaited,
'if desired, one can subscribe to CoreWebView2 events here
'instead of within CoreWebView2InitializationCompleted
'subscribe to events
'AddHandler WebView21.CoreWebView2.DOMContentLoaded, AddressOf CoreWebView2_DOMContentLoaded
'AddHandler WebView21.CoreWebView2.HistoryChanged, AddressOf CoreWebView2_HistoryChanged
LogMsg($"before setting source")
'ToDo: update with desired URL
'after setting Source property execution continues immediately
WebView21.Source = New Uri("http://127.0.0.1:9009/index.html")
LogMsg($"after setting source")
End Sub
Public Function GetWebView2Version() As String
Dim webView2Assembly As System.Reflection.Assembly = GetType(WebView2).Assembly
Return FileVersionInfo.GetVersionInfo(webView2Assembly.Location).ProductVersion
End Function
Public Async Function InitializeCoreWebView2Async(wv As WebView2, Optional userDataFolder As String = Nothing) As Task
Dim options As CoreWebView2EnvironmentOptions = Nothing
Dim webView2Environment As CoreWebView2Environment = Nothing
If String.IsNullOrEmpty(userDataFolder) Then
'create unique name for web cache folder in temp folder
'userDataFolder = System.IO.Path.Combine(System.IO.Path.GetTempPath(), System.Guid.NewGuid().ToString("N"))
userDataFolder = System.IO.Path.Combine(System.IO.Path.GetTempPath(), Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetExecutingAssembly().Location))
End If
'webView2Environment = await CoreWebView2Environment.CreateAsync(@"C:\Program Files (x86)\Microsoft\Edge\Application\105.0.1343.50", userDataFolder, options);
webView2Environment = Await CoreWebView2Environment.CreateAsync(Nothing, userDataFolder, options)
LogMsg("before EnsureCoreWebView2Async")
'wait for CoreWebView2 initialization
Await wv.EnsureCoreWebView2Async(webView2Environment)
LogMsg("after EnsureCoreWebView2Aync")
LogMsg("UserDataFolder folder set to: " & userDataFolder)
End Function
Private Sub LogMsg(ByVal msg As String)
msg = String.Format("{0} {1}", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss:fff"), msg)
Debug.WriteLine(msg)
End Sub
Public Sub WebsiteNavigate(ByVal wv As WebView2, ByVal dest As String)
If Not wv Is Nothing AndAlso Not wv.CoreWebView2 Is Nothing Then
If Not String.IsNullOrEmpty(dest) Then
If Not dest = "about:blank" AndAlso
Not dest.StartsWith("edge://") AndAlso
Not dest.StartsWith("file://") AndAlso
Not dest.StartsWith("http://") AndAlso
Not dest.StartsWith("https://") AndAlso
Not System.Text.RegularExpressions.Regex.IsMatch(dest, "^([A-Z]|[a-z]):") Then
'URL must start with one of the specified strings
'if Not, pre-pend with "http://"
'Debug.Print("Prepending ""http://"" to URL.")
'set value
dest = "http://" & dest
End If
'option 1
wv.Source = New Uri(dest, UriKind.Absolute)
'option 2
'wv.CoreWebView2.Navigate(dest)
End If
End If
End Sub
Private Sub textBoxAddressBar_KeyDown(sender As Object, e As KeyEventArgs) Handles textBoxAddressBar.KeyDown
If e.KeyCode = Keys.Enter AndAlso WebView21 IsNot Nothing Then
WebsiteNavigate(WebView21, textBoxAddressBar.Text)
End If
End Sub
Private Sub btnGo_Click(sender As Object, e As EventArgs) Handles btnGo.Click
WebsiteNavigate(WebView21, textBoxAddressBar.Text)
End Sub
Private Async Sub CoreWebView2_DOMContentLoaded(sender As Object, e As CoreWebView2DOMContentLoadedEventArgs)
LogMsg($"CoreWebView2_DOMContentLoaded")
Dim cwv2 As CoreWebView2 = DirectCast(sender, CoreWebView2)
Try
Dim result As String = Await cwv2.ExecuteScriptAsync("document.getElementById('m.first_name').textContent")
Debug.WriteLine($"result: {result}")
Catch ex As AggregateException
'ToDo: change code as desired
LogMsg($"Error: {ex.Message}")
If ex.InnerExceptions IsNot Nothing Then
For Each ex2 As Exception In ex.InnerExceptions
LogMsg($"{ex2.Message}")
Next
End If
LogMsg($"StackTrace: {ex.StackTrace}")
End Try
End Sub
Private Sub CoreWebView2_HistoryChanged(sender As Object, e As Object)
Dim cwv2 As CoreWebView2 = DirectCast(sender, CoreWebView2)
btnBack.Enabled = WebView21.CoreWebView2.CanGoBack
btnForward.Enabled = WebView21.CoreWebView2.CanGoForward
'update address bar
textBoxAddressBar.Text = cwv2.Source
textBoxAddressBar.Select(textBoxAddressBar.Text.Length, 0)
End Sub
Private Sub WebView21_CoreWebView2InitializationCompleted(sender As Object, e As CoreWebView2InitializationCompletedEventArgs) Handles WebView21.CoreWebView2InitializationCompleted
Dim wv As WebView2 = DirectCast(sender, WebView2)
LogMsg($"WebView21_CoreWebView2InitializationCompleted")
LogMsg($"UserDataFolder: {WebView21.CoreWebView2.Environment.UserDataFolder}")
LogMsg($"Edge Browser version: {WebView21.CoreWebView2.Environment.BrowserVersionString}")
'subscribe to events
AddHandler wv.CoreWebView2.DOMContentLoaded, AddressOf CoreWebView2_DOMContentLoaded
AddHandler wv.CoreWebView2.HistoryChanged, AddressOf CoreWebView2_HistoryChanged
End Sub
Private Sub WebView21_NavigationCompleted(sender As Object, e As CoreWebView2NavigationCompletedEventArgs) Handles WebView21.NavigationCompleted
LogMsg($"WebView21_NavigationCompleted")
End Sub
End Class
选项 2- 显式初始化(CreationProperties)
Imports System.IO
Imports Microsoft.Web.WebView2.Core
Imports Microsoft.Web.WebView2.WinForms
Public Class Form1
Private Async Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
LogMsg($"WebView2 version: {GetWebView2Version()}")
'set UserDataFolder
Dim userDataFolder As String = Path.Combine(Path.GetTempPath(), Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetExecutingAssembly().Location))
WebView21.CreationProperties = New CoreWebView2CreationProperties() With {.UserDataFolder = userDataFolder}
'explicitly initialize CoreWebView2
Await WebView21.EnsureCoreWebView2Async()
'since we've used explicit initialization, which is Awaited,
'if desired, one can subscribe to CoreWebView2 events here
'instead of within CoreWebView2InitializationCompleted
'subscribe to events
'AddHandler WebView21.CoreWebView2.DOMContentLoaded, AddressOf CoreWebView2_DOMContentLoaded
'AddHandler WebView21.CoreWebView2.HistoryChanged, AddressOf CoreWebView2_HistoryChanged
LogMsg($"before setting source")
'ToDo: update with desired URL
'after setting Source property execution continues immediately
WebView21.Source = New Uri("http://127.0.0.1:9009/index.html")
LogMsg($"after setting source")
End Sub
Public Function GetWebView2Version() As String
Dim webView2Assembly As System.Reflection.Assembly = GetType(WebView2).Assembly
Return FileVersionInfo.GetVersionInfo(webView2Assembly.Location).ProductVersion
End Function
Private Sub LogMsg(ByVal msg As String)
msg = String.Format("{0} {1}", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss:fff"), msg)
Debug.WriteLine(msg)
End Sub
Public Sub WebsiteNavigate(ByVal wv As WebView2, ByVal dest As String)
If Not wv Is Nothing AndAlso Not wv.CoreWebView2 Is Nothing Then
If Not String.IsNullOrEmpty(dest) Then
If Not dest = "about:blank" AndAlso
Not dest.StartsWith("edge://") AndAlso
Not dest.StartsWith("file://") AndAlso
Not dest.StartsWith("http://") AndAlso
Not dest.StartsWith("https://") AndAlso
Not System.Text.RegularExpressions.Regex.IsMatch(dest, "^([A-Z]|[a-z]):") Then
'URL must start with one of the specified strings
'if Not, pre-pend with "http://"
'Debug.Print("Prepending ""http://"" to URL.")
'set value
dest = "http://" & dest
End If
'option 1
wv.Source = New Uri(dest, UriKind.Absolute)
'option 2
'wv.CoreWebView2.Navigate(dest)
End If
End If
End Sub
Private Sub textBoxAddressBar_KeyDown(sender As Object, e As KeyEventArgs) Handles textBoxAddressBar.KeyDown
If e.KeyCode = Keys.Enter AndAlso WebView21 IsNot Nothing Then
WebsiteNavigate(WebView21, textBoxAddressBar.Text)
End If
End Sub
Private Sub btnGo_Click(sender As Object, e As EventArgs) Handles btnGo.Click
WebsiteNavigate(WebView21, textBoxAddressBar.Text)
End Sub
Private Async Sub CoreWebView2_DOMContentLoaded(sender As Object, e As CoreWebView2DOMContentLoadedEventArgs)
LogMsg($"CoreWebView2_DOMContentLoaded")
Dim cwv2 As CoreWebView2 = DirectCast(sender, CoreWebView2)
Try
Dim result As String = Await cwv2.ExecuteScriptAsync("document.getElementById('m.first_name').textContent")
Debug.WriteLine($"result: {result}")
Catch ex As AggregateException
'ToDo: change code as desired
LogMsg($"Error: {ex.Message}")
If ex.InnerExceptions IsNot Nothing Then
For Each ex2 As Exception In ex.InnerExceptions
LogMsg($"{ex2.Message}")
Next
End If
LogMsg($"StackTrace: {ex.StackTrace}")
End Try
End Sub
Private Sub CoreWebView2_HistoryChanged(sender As Object, e As Object)
Dim cwv2 As CoreWebView2 = DirectCast(sender, CoreWebView2)
btnBack.Enabled = WebView21.CoreWebView2.CanGoBack
btnForward.Enabled = WebView21.CoreWebView2.CanGoForward
'update address bar
textBoxAddressBar.Text = cwv2.Source
textBoxAddressBar.Select(textBoxAddressBar.Text.Length, 0)
End Sub
Private Sub WebView21_CoreWebView2InitializationCompleted(sender As Object, e As CoreWebView2InitializationCompletedEventArgs) Handles WebView21.CoreWebView2InitializationCompleted
Dim wv As WebView2 = DirectCast(sender, WebView2)
LogMsg($"WebView21_CoreWebView2InitializationCompleted")
LogMsg($"UserDataFolder: {WebView21.CoreWebView2.Environment.UserDataFolder}")
LogMsg($"Edge Browser version: {WebView21.CoreWebView2.Environment.BrowserVersionString}")
'subscribe to events
AddHandler wv.CoreWebView2.DOMContentLoaded, AddressOf CoreWebView2_DOMContentLoaded
AddHandler wv.CoreWebView2.HistoryChanged, AddressOf CoreWebView2_HistoryChanged
End Sub
Private Sub WebView21_NavigationCompleted(sender As Object, e As CoreWebView2NavigationCompletedEventArgs) Handles WebView21.NavigationCompleted
LogMsg($"WebView21_NavigationCompleted")
End Sub
End Class
选项 3- 隐式初始化(CreationProperties)
Imports System.IO
Imports Microsoft.Web.WebView2.Core
Imports Microsoft.Web.WebView2.WinForms
Public Class Form1
Private Async Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
LogMsg($"WebView2 version: {GetWebView2Version()}")
'set UserDataFolder
Dim userDataFolder As String = Path.Combine(Path.GetTempPath(), Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetExecutingAssembly().Location))
WebView21.CreationProperties = New CoreWebView2CreationProperties() With {.UserDataFolder = userDataFolder}
LogMsg($"before setting source")
'CoreWebView2 will be implicitly initialized when
'Source property is set
'this doesn't wait for CoreWebView2 intialization to complete
'so any code that exists after this statement may execute
'prior to CoreWebView2 intialization completing
WebView21.Source = New Uri("http://127.0.0.1:9009/index.html")
LogMsg($"after setting source")
End Sub
Public Function GetWebView2Version() As String
Dim webView2Assembly As System.Reflection.Assembly = GetType(WebView2).Assembly
Return FileVersionInfo.GetVersionInfo(webView2Assembly.Location).ProductVersion
End Function
Private Sub LogMsg(ByVal msg As String)
msg = String.Format("{0} {1}", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss:fff"), msg)
Debug.WriteLine(msg)
End Sub
Public Sub WebsiteNavigate(ByVal wv As WebView2, ByVal dest As String)
If Not wv Is Nothing AndAlso Not wv.CoreWebView2 Is Nothing Then
If Not String.IsNullOrEmpty(dest) Then
If Not dest = "about:blank" AndAlso
Not dest.StartsWith("edge://") AndAlso
Not dest.StartsWith("file://") AndAlso
Not dest.StartsWith("http://") AndAlso
Not dest.StartsWith("https://") AndAlso
Not System.Text.RegularExpressions.Regex.IsMatch(dest, "^([A-Z]|[a-z]):") Then
'URL must start with one of the specified strings
'if Not, pre-pend with "http://"
'Debug.Print("Prepending ""http://"" to URL.")
'set value
dest = "http://" & dest
End If
'option 1
wv.Source = New Uri(dest, UriKind.Absolute)
'option 2
'wv.CoreWebView2.Navigate(dest)
End If
End If
End Sub
Private Sub textBoxAddressBar_KeyDown(sender As Object, e As KeyEventArgs) Handles textBoxAddressBar.KeyDown
If e.KeyCode = Keys.Enter AndAlso WebView21 IsNot Nothing Then
WebsiteNavigate(WebView21, textBoxAddressBar.Text)
End If
End Sub
Private Sub btnGo_Click(sender As Object, e As EventArgs) Handles btnGo.Click
WebsiteNavigate(WebView21, textBoxAddressBar.Text)
End Sub
Private Async Sub CoreWebView2_DOMContentLoaded(sender As Object, e As CoreWebView2DOMContentLoadedEventArgs)
LogMsg($"CoreWebView2_DOMContentLoaded")
Dim cwv2 As CoreWebView2 = DirectCast(sender, CoreWebView2)
Try
Dim result As String = Await cwv2.ExecuteScriptAsync("document.getElementById('m.first_name').textContent")
Debug.WriteLine($"result: {result}")
Catch ex As AggregateException
'ToDo: change code as desired
LogMsg($"Error: {ex.Message}")
If ex.InnerExceptions IsNot Nothing Then
For Each ex2 As Exception In ex.InnerExceptions
LogMsg($"{ex2.Message}")
Next
End If
LogMsg($"StackTrace: {ex.StackTrace}")
End Try
End Sub
Private Sub CoreWebView2_HistoryChanged(sender As Object, e As Object)
Dim cwv2 As CoreWebView2 = DirectCast(sender, CoreWebView2)
btnBack.Enabled = WebView21.CoreWebView2.CanGoBack
btnForward.Enabled = WebView21.CoreWebView2.CanGoForward
'update address bar
textBoxAddressBar.Text = cwv2.Source
textBoxAddressBar.Select(textBoxAddressBar.Text.Length, 0)
End Sub
Private Sub WebView21_CoreWebView2InitializationCompleted(sender As Object, e As CoreWebView2InitializationCompletedEventArgs) Handles WebView21.CoreWebView2InitializationCompleted
Dim wv As WebView2 = DirectCast(sender, WebView2)
LogMsg($"WebView21_CoreWebView2InitializationCompleted")
LogMsg($"UserDataFolder: {WebView21.CoreWebView2.Environment.UserDataFolder}")
LogMsg($"Edge Browser version: {WebView21.CoreWebView2.Environment.BrowserVersionString}")
'subscribe to events
AddHandler wv.CoreWebView2.DOMContentLoaded, AddressOf CoreWebView2_DOMContentLoaded
AddHandler wv.CoreWebView2.HistoryChanged, AddressOf CoreWebView2_HistoryChanged
End Sub
Private Sub WebView21_NavigationCompleted(sender As Object, e As CoreWebView2NavigationCompletedEventArgs) Handles WebView21.NavigationCompleted
LogMsg($"WebView21_NavigationCompleted")
End Sub
End Class
这是我用于测试的 HTML:
索引.html
<html>
<head>
</head>
<body>
<div id="view_m" style="display: block;">
<div id="form_small_left">
<table id="view_m_1" style="display: block;">
<tbody>
<tr>
<th>First name:</th>
<td id="m.first_name">Margeaet</td>
</tr>
<tr>
<th>Last name:</th>
<td id="m.last_name">Bill</td>
</tr>
</tbody>
</div>
</div>
</body>
</html>
资源