前言
目前的windows/Linux下的UI方案,以Qt為主,F(xiàn)lutter, Electron為輔,其他的各種UI都是不堪大用。眾所周知,Electron的資源占用和內(nèi)容占用太大,效率不行,所以有了后續(xù)各種跨語(yǔ)言的Web套殼方案:
- walls go語(yǔ)言下web套殼
- tarui Rust下的web套殼
除了使用CEF的Qt/C++/C#方案,Qt+WebEngine, 目前在Windows下各家的最終歸路都轉(zhuǎn)向Webview2方案,可以極大地減少發(fā)布的程序的大小。
備注:
- VS2019支持.Net Framework(~4.8), 對(duì)于Net Core 3 和Net 5 支持并不是很完善,并且已過(guò)了維護(hù)期
- VS2022對(duì)Net 6, 7以及Net Framework 4.8 的支持都很完善,建議使用此搭配
C# Winform下Webview2方案Demo
.Net Framework 使用4.8
UI Form核心Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace webview
{
public partial class Form1 : Form
{
private webTool tool;
public Form1()
{
InitializeComponent();
// https://blog.csdn.net/bashendixie5/article/details/126432821
tool = new webTool(ref webView2_main);
initWebview2();
}
private async void initWebview2()
{
var userData = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), Application.ProductName);
var env = await Microsoft.Web.WebView2.Core.CoreWebView2Environment.CreateAsync(null, userData);
await webView2_main.EnsureCoreWebView2Async(env);
//webView2_main.CoreWebView2InitializationCompleted += WebView2_main_CoreWebView2InitializationCompleted;
// title 發(fā)生變化時(shí)
webView2_main.CoreWebView2.DocumentTitleChanged += CoreWebView2_DocumentTitleChanged;
// 有新的網(wǎng)頁(yè)請(qǐng)求時(shí), 攔截
webView2_main.CoreWebView2.NewWindowRequested += CoreWebView2_NewWindowRequested;
// add binding with C#
webView2_main.CoreWebView2.AddHostObjectToScript("tool", tool);
}
private void CoreWebView2_NewWindowRequested(object sender, Microsoft.Web.WebView2.Core.CoreWebView2NewWindowRequestedEventArgs e)
{
var defer = e.GetDeferral();
e.Handled = true;
webView2_main.Source = new Uri(e.Uri);
// 或者新開(kāi)一個(gè)windows
//e.NewWindow = webView2_main.CoreWebView2;
defer.Complete();
}
private void CoreWebView2_DocumentTitleChanged(object sender, object e)
{
Text = webView2_main.CoreWebView2.DocumentTitle;
}
private void button_go_Click(object sender, EventArgs e)
{
webView2_main.Source = new Uri(textBox_url.Text.Trim());
}
private void button_back_Click(object sender, EventArgs e)
{
if(webView2_main.CanGoBack) webView2_main.GoBack();
}
private void button_forward_Click(object sender, EventArgs e)
{
if (webView2_main.CanGoForward) webView2_main.GoForward();
}
private void button_test_Click(object sender, EventArgs e)
{
var a = new Dictionary<string, object>();
a["123"] = "xxxyy";
a["abc"] = 15.23;
a["0"] = true;
tool.callJs(a);
}
}
}
依賴的object必須實(shí)現(xiàn)COM接口:
using Microsoft.Web.WebView2.WinForms;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
// https://learn.microsoft.com/zh-tw/dotnet/api/microsoft.web.webview2.core.corewebview2.addhostobjecttoscript?view=webview2-dotnet-0.9.628-prerelease
namespace webview
{
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class webTool
{
private WebView2 web;
public webTool(ref WebView2 web)
{
this.web = web;
}
public void msg(string txt)
{
MessageBox.Show(txt, "By Form", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
public void callJs(object args)
{
string js = $"console.log({JsonConvert.SerializeObject(args)})";
web.ExecuteScriptAsync(js);
}
}
}
html Demo參考:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JS with C# Demo</title>
</head>
<script>
var tool = window.chrome.webview.hostObjects.tool;
function call_C(){
console.log(tool);
tool.msg("hello, i am from web ui");
alert("ok");
}
</script>
<body>
<button onclick="call_C()">Call C# Code with message</button>
<pre>
var tool = window.chrome.webview.hostObjects.tool;
function call_C(){
console.log(tool);
tool.msg("hello, i am from web ui");
alert("ok");
}
</pre>
</body>
</html>
程序Setup打包
對(duì)于打包程序,使用Visual Studio Setup Installer Project
創(chuàng)建,參考:
- Unistall 提供
- 手動(dòng)拖動(dòng)文件夾可以快速添加
- 需要手動(dòng)判斷需要的文件
-
Program File
一般無(wú)寫(xiě)權(quán)限,使用AppData/Local/xxx
作為自己的程序數(shù)據(jù)目錄
參考文章:
- https://www.pianshen.com/article/14091375659/
- https://blog.csdn.net/jk_rou/article/details/130307402
- https://betheme.net/yidongkaifa/72139.html?action=onClick
Webview2 控件找不到
如果遇到Webview2控件在Toolbox的工具箱中找不到,可以考慮下面2個(gè)方案:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-522409.html
- 檢查webview2的版本依賴,一般有對(duì)應(yīng)Edge版本要求,所以,升級(jí)Edge就好了
- 當(dāng)前Webview2安裝包沒(méi)有你使用的net framework/net core版本,但是實(shí)際上還是可以用的,參照如下方法,手動(dòng)添加到工具箱就可以啦。
**Solution**
I found the solution for adding the WebView2 control to the toolbox on the GitHub site you provided, post is [here](https://github.com/MicrosoftEdge/WebViewFeedback/issues/323). Here are the details of the solution for others to follow:
- Right-click on the toolbar in Visual Studios
- Select 'Choose Items...'
- Click the '.NET Framework Components' tab
- Click 'Browse', may have to wait for scan to finish
- Navigate to '<your-solution-folder>\\packages\\Microsoft.Web.WebView2.0.9.538-prerelease\\lib\\net462'
- Select the correct DLL for your application type
- Once the file is selected click the 'OK' button in the window
Done! Now you can access the WebView2 control in the toolbox. If you're using .Net Core then try replacing 'net462' with 'netcoreapp3.0' in the folder path.
注意:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-522409.html
- Webview2目前并不是支持所有的net framework!!!
- 如果遇上Webview2安裝完成后在ToolBox不顯示問(wèn)題,需要檢查Edge瀏覽器版本。還要核對(duì)你使用的net framework版本。參考這里:https://www.nuget.org/packages/Microsoft.Web.WebView2#supportedframeworks-body-tab。
- 如果你用net 4.8 可以考慮手動(dòng)添加net 4.5的dll使用,木有問(wèn)題。但是net core 6/7 使用 3的dll肯定是不行的
到了這里,關(guān)于C# Winform 中使用 Webview2的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!