WebView2 EnsureCoreWebView2Async 从不 returns
WebView2 EnsureCoreWebView2Async never returns
在我的 WPF 应用程序中,我需要显示一个 html 字符串,并且我知道我需要在调用 NavigateToString 之前调用 EnsureCoreWebView2Async 方法,否则 CoreWebView 将为 null,并且我会出现异常。问题是等待 EnsureCoreWebView2Async 永远不会结束。
我创建了一个小应用程序以重现问题(并排除与我的大项目相关的问题),问题是一样的。
- 如果我将 WebView2 的源 属性 设置为传递 Url,那么它就可以工作了!
- 如果我在不调用 EnsureCoreWebView2Async 的情况下调用 NavigateToString,则会出现异常(如预期的那样)。
- 如果我在调用 NavigateToString 之前或设置 Source 之前调用 EnsureCoreWebView2Async 属性(这应该不是问题,因为根据文档多次调用它应该不会有任何影响)然后它永远挂起。
调用没有引发异常,控制台中也没有消息。很郁闷。
这里是示例应用程序的代码(我主 window 有 2 个按钮,一个打开 url 和一个加载 html 字符串 - 第一个有效):
<Window x:Class="WebViewApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WebViewApp" xmlns:wpf="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<Button Width="200" Height="40" Click="OpenUrl_Click">Open url</Button>
<Button Width="200" Height="40" Click="OpenHtml_Click">Open html</Button>
</StackPanel></Window>
MainWindow 后面的代码:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private async void OpenUrl_Click(object sender, RoutedEventArgs e)
{
var browserWindow = new WebWindow();
//await browserWindow.Initialize(); // this also never completes
browserWindow.OpenUrl("http://www.microsoft.com");
browserWindow.Show();
}
private async void OpenHtml_Click(object sender, RoutedEventArgs e)
{
var browserWindow = new WebWindow();
await browserWindow.Initialize();
browserWindow.LoadHtml(@"<html><head><title>Test title</title></head><body><p>Test</p></body></html>");
browserWindow.Show();
}
}
这里是browserViewxaml(添加WebView2 nuget包):
<Window x:Class="WebViewApp.WebWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WebViewApp" xmlns:wpf="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
mc:Ignorable="d"
Title="WebWindow" Height="450" Width="800">
<Grid>
<wpf:WebView2 Name="WpfBrowser" />
</Grid></Window>
以及后面的代码:
public partial class WebWindow : Window
{
public WebWindow()
{
InitializeComponent();
}
public async Task Initialize()
{
try
{
await WpfBrowser.EnsureCoreWebView2Async(); // never completes
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
}
}
public void LoadHtml(string html)
{
WpfBrowser.NavigateToString(html);
}
public void OpenUrl(string url)
{
WpfBrowser.Source = new Uri(url);
}
}
我也尝试过更改 Target 平台,但没有任何改变。
您应该推迟初始化 webview,直到调用 OnContentRendered。我更改了您的代码,它很有魅力。请参阅以下更改。
public partial class WebWindow : Window
{
private string _url;
private string _html;
public WebWindow()
{
InitializeComponent();
}
protected override async void OnContentRendered(EventArgs e)
{
base.OnContentRendered(e);
try
{
var webView2Environment = await CoreWebView2Environment.CreateAsync();
await WpfBrowser.EnsureCoreWebView2Async(webView2Environment);
if(!string.IsNullOrEmpty(_url))
WpfBrowser.Source = new Uri(_url);
else if(!string.IsNullOrEmpty(_html))
WpfBrowser.NavigateToString(_html);
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
}
}
public void ShowFromUrl(string url)
{
_url = url;
Show();
}
public void ShowFromHtml(string html)
{
_html = html;
Show();
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private async void OpenUrl_Click(object sender, RoutedEventArgs e)
{
var browserWindow = new WebWindow();
browserWindow.ShowFromUrl("http://www.microsoft.com");
}
private async void OpenHtml_Click(object sender, RoutedEventArgs e)
{
var browserWindow = new WebWindow();
browserWindow.ShowFromHtml(@"<html><head><title>Test title</title></head><body><p>Testsdfsdfsdfsdfdsfdsfklsdkflkdlf<br>dsfdsfdsfdsfsdfdsfds</p></body></html>");
}
}
您还可以从我的 git 存储库中查看执行类似操作的代码。
KioskBrowser (GitHub)
在我的 WPF 应用程序中,我需要显示一个 html 字符串,并且我知道我需要在调用 NavigateToString 之前调用 EnsureCoreWebView2Async 方法,否则 CoreWebView 将为 null,并且我会出现异常。问题是等待 EnsureCoreWebView2Async 永远不会结束。
我创建了一个小应用程序以重现问题(并排除与我的大项目相关的问题),问题是一样的。
- 如果我将 WebView2 的源 属性 设置为传递 Url,那么它就可以工作了!
- 如果我在不调用 EnsureCoreWebView2Async 的情况下调用 NavigateToString,则会出现异常(如预期的那样)。
- 如果我在调用 NavigateToString 之前或设置 Source 之前调用 EnsureCoreWebView2Async 属性(这应该不是问题,因为根据文档多次调用它应该不会有任何影响)然后它永远挂起。 调用没有引发异常,控制台中也没有消息。很郁闷。
这里是示例应用程序的代码(我主 window 有 2 个按钮,一个打开 url 和一个加载 html 字符串 - 第一个有效):
<Window x:Class="WebViewApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WebViewApp" xmlns:wpf="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<Button Width="200" Height="40" Click="OpenUrl_Click">Open url</Button>
<Button Width="200" Height="40" Click="OpenHtml_Click">Open html</Button>
</StackPanel></Window>
MainWindow 后面的代码:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private async void OpenUrl_Click(object sender, RoutedEventArgs e)
{
var browserWindow = new WebWindow();
//await browserWindow.Initialize(); // this also never completes
browserWindow.OpenUrl("http://www.microsoft.com");
browserWindow.Show();
}
private async void OpenHtml_Click(object sender, RoutedEventArgs e)
{
var browserWindow = new WebWindow();
await browserWindow.Initialize();
browserWindow.LoadHtml(@"<html><head><title>Test title</title></head><body><p>Test</p></body></html>");
browserWindow.Show();
}
}
这里是browserViewxaml(添加WebView2 nuget包):
<Window x:Class="WebViewApp.WebWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WebViewApp" xmlns:wpf="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
mc:Ignorable="d"
Title="WebWindow" Height="450" Width="800">
<Grid>
<wpf:WebView2 Name="WpfBrowser" />
</Grid></Window>
以及后面的代码:
public partial class WebWindow : Window
{
public WebWindow()
{
InitializeComponent();
}
public async Task Initialize()
{
try
{
await WpfBrowser.EnsureCoreWebView2Async(); // never completes
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
}
}
public void LoadHtml(string html)
{
WpfBrowser.NavigateToString(html);
}
public void OpenUrl(string url)
{
WpfBrowser.Source = new Uri(url);
}
}
我也尝试过更改 Target 平台,但没有任何改变。
您应该推迟初始化 webview,直到调用 OnContentRendered。我更改了您的代码,它很有魅力。请参阅以下更改。
public partial class WebWindow : Window
{
private string _url;
private string _html;
public WebWindow()
{
InitializeComponent();
}
protected override async void OnContentRendered(EventArgs e)
{
base.OnContentRendered(e);
try
{
var webView2Environment = await CoreWebView2Environment.CreateAsync();
await WpfBrowser.EnsureCoreWebView2Async(webView2Environment);
if(!string.IsNullOrEmpty(_url))
WpfBrowser.Source = new Uri(_url);
else if(!string.IsNullOrEmpty(_html))
WpfBrowser.NavigateToString(_html);
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
}
}
public void ShowFromUrl(string url)
{
_url = url;
Show();
}
public void ShowFromHtml(string html)
{
_html = html;
Show();
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private async void OpenUrl_Click(object sender, RoutedEventArgs e)
{
var browserWindow = new WebWindow();
browserWindow.ShowFromUrl("http://www.microsoft.com");
}
private async void OpenHtml_Click(object sender, RoutedEventArgs e)
{
var browserWindow = new WebWindow();
browserWindow.ShowFromHtml(@"<html><head><title>Test title</title></head><body><p>Testsdfsdfsdfsdfdsfdsfklsdkflkdlf<br>dsfdsfdsfdsfsdfdsfds</p></body></html>");
}
}
您还可以从我的 git 存储库中查看执行类似操作的代码。 KioskBrowser (GitHub)