WebView2和CEF相比,在WPF中CEF相当于把渲染的界面生成图片再加载,而WebView2则没有这一步,性能有显著提升。
但是这种方式暂时没有找到支持Flash的方法。
这种方式可以支持Win7,XP尚未进行测试。
但是在安装的时候64位的Win7竟然无法安装32位的WebView2 运行时,所以建议64位的就安装64位的运行时。
官方教程 https://docs.microsoft.com/zh-cn/microsoft-edge/webview2/get-started/wpf
WebView2 实在诱人,最新的 Edge(Chromium) 性能强悍,而且所有使用 WebView2 的应用可以共用一个运行时(说人话就是一个安装了应用时,其他应用就不用装了)。
Windows 11 已经自带 WebView2 ,就连 Office 也会自动部署 WebView2 ,目前 WebView2 已经被部署到 2亿台电脑,并且还在继续增加 …… 未来是属于 WebView2 的。
重要的是 WebView2 仍然支持老旧的、即将被淘汰的 Windows 7 —— 拥有良好的兼容性。
WebView2是依赖于Edge chromium内核的,有如下三种方式可以获取:
这三种方式运行效果基本一致,主要特点是:
所以这里我推荐第二种方式。
下载地址:
https://developer.microsoft.com/zh-cn/microsoft-edge/webview2/#download-section
安装Microsoft.Web.WebView2程序包
Install-Package Microsoft.Web.WebView2
添加名字空间
xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
添加控件
<wv2:WebView2 Name="webView" Source="https://www.psvmc.cn"/>
注意
建议专门一个页面进行检测,检测成功后再跳转到展示页面。
public static bool IsInstallWebview2()
{
string result = "";
try
{
result = CoreWebView2Environment.GetAvailableBrowserVersionString();
}
catch (System.Exception)
{
}
if (result == "" || result == null)
{
return false;
}
return true;
}
private async Task InstallRuntimeAsync()
{
// 解决下载文件报错:请求被中止: 未能创建 SSL/TLS 安全通道
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
var webClient = new WebClient();
bool isDownload = false;
string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
string MicrosoftEdgeWebview2Setup = System.IO.Path.Combine(desktopPath, "MicrosoftEdgeWebview2Setup.exe");
try
{
webClient.DownloadFileCompleted += (s, e) =>
{
if (e.Error != null)
{
MessageBox.Show("下载失败:" + e.Error.Message);
}
else if (e.Cancelled)
{
MessageBox.Show("下载取消");
}
else
{
isDownload = true;
}
};
await webClient.DownloadFileTaskAsync("https://go.microsoft.com/fwlink/p/?LinkId=2124703", MicrosoftEdgeWebview2Setup);
}
catch (Exception)
{
}
if (isDownload)
{
await Task.Delay(300);
await Task.Run(
() =>
{
Process.Start(MicrosoftEdgeWebview2Setup, " /install").WaitForExit();
}
);
if (IsInstallWebview2())
{
if (
Environment.OSVersion.Version.Major < 6 ||
Environment.OSVersion.Version.Major == 6 &&
Environment.OSVersion.Version.Minor <= 1
)
{
//Restart application in Win7 or lower OS
var location = System.Reflection.Assembly.GetExecutingAssembly().Location;
location = location.Replace(".dll", ".exe");
Process.Start(location);
}
else
{
System.Windows.Forms.Application.Restart();
}
Close();
}
}
}
调用
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
webView.CoreWebView2InitializationCompleted += WebView_CoreWebView2InitializationCompleted;
sendBtn.Click += SendBtn_ClickAsync;
await webView.EnsureCoreWebView2Async();
if (!IsInstallWebview2())
{
await InstallRuntimeAsync();
}
}
其中
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
解决在Win7环境下载文件报错:
请求被中止: 未能创建 SSL/TLS 安全通道
if (
Environment.OSVersion.Version.Major < 6 ||
Environment.OSVersion.Version.Major == 6 &&
Environment.OSVersion.Version.Minor <= 1
)
{
//Restart application in Win7 or lower OS
var location = System.Reflection.Assembly.GetExecutingAssembly().Location;
location = location.Replace(".dll", ".exe");
Process.Start(location);
}
else
{
System.Windows.Forms.Application.Restart();
}
Close();
你可以读取HTML文件,然后读取NavigateToString
private void Window_Loaded(object sender, RoutedEventArgs e)
{
webView.CoreWebView2InitializationCompleted += WebView_CoreWebView2InitializationCompleted;
webView.EnsureCoreWebView2Async();
}
private void WebView_CoreWebView2InitializationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e)
{
string rootPath = Environment.CurrentDirectory;
string filepath = System.IO.Path.Combine(rootPath, "html", "index.html");
Console.WriteLine(filepath);
if (webView != null && webView.CoreWebView2 != null)
{
string text = System.IO.File.ReadAllText(filepath);
webView.CoreWebView2.NavigateToString(text);
}
}
或者
你也可以通过Navigate
连接到本地文件:
string rootPath = Environment.CurrentDirectory;
string filepath = System.IO.Path.Combine(rootPath, "html", "index.html");
webView.Source = new Uri("file:///" + filepath);
本机代码
if (webView != null && webView.CoreWebView2 != null)
{
webView.CoreWebView2.PostWebMessageAsString(inputTB.Text);
}
JS代码
<script type="text/javascript">
window.chrome.webview.addEventListener('message', arg => {
document.querySelector(".outer").innerHTML = arg.data;
});
</script>
或者发送JSON
if (webView != null && webView.CoreWebView2 != null)
{
webView.CoreWebView2.PostWebMessageAsJson("{\"color\":\"blue\"}");
}
JS接收
<script type="text/javascript">
window.chrome.webview.addEventListener('message', arg => {
document.querySelector(".outer").innerHTML = arg.data.color;
});
</script>
唯一的差别在于
接收的时候会自动转换为JSON对象。不过我还是建议传递字符串,转换的操作放在JS中处理。
private async void SendBtn_ClickAsync(object sender, RoutedEventArgs e)
{
if (webView != null && webView.CoreWebView2 != null)
{
await webView.CoreWebView2.ExecuteScriptAsync("alert('123')");
}
}
或者调用JS方法
function showmsg(msg) {
alert(msg);
}
本机代码
private async void SendBtn_ClickAsync(object sender, RoutedEventArgs e)
{
if (webView != null && webView.CoreWebView2 != null)
{
await webView.CoreWebView2.ExecuteScriptAsync("showmsg('你好')");
}
}
定义数据交互的类
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class ScriptCallbackObject
{
public string GetMessageInfo()
{
return "C#返回的信息";
}
public void ShowMessage(string arg)
{
Console.WriteLine(arg);
MessageBox.Show("【网页调用C#】:" + arg);
}
}
代码中注册事件
private void Window_Loaded(object sender, RoutedEventArgs e)
{
webView.CoreWebView2InitializationCompleted += WebView_CoreWebView2InitializationCompleted;
webView.EnsureCoreWebView2Async();
}
private void WebView_CoreWebView2InitializationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e)
{
if (webView != null && webView.CoreWebView2 != null)
{
//注册csobj脚本c#互操作
webView.CoreWebView2.AddHostObjectToScript("csobj", new ScriptCallbackObject());
//注册全局变量csobj
webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("var csobj = window.chrome.webview.hostObjects.csobj;");
webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("var csobj_sync= window.chrome.webview.hostObjects.sync.csobj;");
//加载页面
string rootPath = Environment.CurrentDirectory;
string filepath = System.IO.Path.Combine(rootPath, "html", "index.html");
string text = System.IO.File.ReadAllText(filepath);
webView.CoreWebView2.NavigateToString(text);
}
}
HTML中
异步调用取值
<script type="text/javascript">
function myfunc() {
window.chrome.webview.hostObjects.csobj.GetMessageInfo()
.then(
msg => {
document.querySelector(".mytext").innerText = msg;
}
)
}
</script>
当然上面的代码也可以简写为
function myfunc() {
csobj.GetMessageInfo()
.then(
msg => {
document.querySelector(".mytext").innerText = msg;
}
)
}
这是因为我们已经在C#中创建了JS的对象
webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("var csobj = window.chrome.webview.hostObjects.csobj;");
同步调用取值
<script type="text/javascript">
function myfunc() {
var msg = window.chrome.webview.hostObjects.sync.csobj.GetMessageInfo();
document.querySelector(".mytext").innerText = msg;
}
</script>
同步调用
<script type="text/javascript">
function myfunc() {
window.chrome.webview.hostObjects.sync.csobj.ShowMessage("你好吗");
}
</script>
注意
window.chrome.webview.hostObjects.csobj
是异步的,要想同步就要用window.chrome.webview.hostObjects.sync.csobj
。
很遗憾,现在还没找到WebView2支持Flash的方式。
目前要想支持Flash只有两种选择:
WebBrowser
,系统安装Flash插件(IE内核)扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有