您现在的位置是:网站首页> C#技术
C# WebView2的相关总结
- C#技术
- 2024-09-06
- 1097人已阅读
C# WebView2的相关总结
C# 使用Microsoft Edge WebView2的相关总结
用WebBrowser获取JS动态加载以后的页面代码并保存图片
C# 使用Microsoft Edge WebView2的相关总结
一、C#和js互相调用
1、js调用C#
C#代码如下:
为避免出现手机端排版混乱,用必要的占位字符进行处理
webView.CoreWebView2.AddHostObjectToScript("webBrowserObj", new ScriptCallbackObject());
await webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("var webBrowserObj= window.chrome.webview.hostObjects.webBrowserObj;");
像网页里面注入变量,这样网页调用时候不用每次写window.chrome.webview.hostObjects.webBrowserObj调用,最主要的是为了兼容之前cef里面Js的写法。
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
/// <summary>
/// 网页调用C#方法
/// </summary>
public class ScriptCallbackObject
{
public string UserName { get; set; } = "我是C#属性";
public void ShowMessage()
{
MessageBox.Show("网页调用C#");
}
public void ShowMessageArg(string arg)
{
MessageBox.Show("【网页调用C#】:" + arg);
}
public string GetData(string arg)
{
return "【网页调用C#获取数据】;" + arg;
}
[System.Runtime.CompilerServices.IndexerName("Items")]
public string this[int index]
{
get { return m_dictionary[index]; }
set { m_dictionary[index] = value; }
}
private Dictionary<int, string> m_dictionary = new Dictionary<int, string>();
}
JS调用如下;
function callCsharp2() {
var data2 = $("#txtArg").attr("value"); //大坑 值不会时刻变化 // alert(data2); var data = $("#txtArg").val();
window.chrome.webview.hostObjects.webBrowserObj.ShowMessageArg(data); //window.chrome.webview.postMessage(data); };
async function callCsharp3() {
var data = $("#txtArg").val();
var result = await webBrowserObj.GetData(data);
alert(result);
};
async function callCsharp4() {
const propValue = await webBrowserObj.UserName;
console.log(propValue);
alert(propValue);
};
2、C#调用JS
private void callJS_Click(object sender, RoutedEventArgs e)
{
webView.CoreWebView2.ExecuteScriptAsync("ShowMessage()");
}
private void callJSArg_Click(object sender, RoutedEventArgs e)
{
webView.CoreWebView2.ExecuteScriptAsync($"ShowMessageArg('{txtArg.Text}')");
}
private async void callJSGetData_Click(object sender, RoutedEventArgs e)
{
var jsResult = await webView.CoreWebView2.ExecuteScriptAsync($"GetData('{txtArg.Text}')");
if (!string.IsNullOrEmpty(jsResult))
{
MessageBox.Show(jsResult);
}
}
js里面的代码
//2、C#调用网页
var jsVar = '123';
function Hello() {
alert('调用Js' + jsVar);
};
function ShowMessage() {
alert('我是网页');
};
function ShowMessageArg(arg) {
alert('【我是网页消息框】' + arg);
};
function GetData(arg) {
return '【我是网页返回给你】:' + arg;
};
二、缩放问题
webView.CoreWebView2.Settings.IsZoomControlEnabled = false;
只能禁止鼠标缩放,不能禁止手势缩放。 见问题
另外触摸到底部门的时候 有弹跳,暂时也无法解决。
以上就是C# 使用Microsoft Edge WebView2的相关总结的详细内容,更多关于C# 使用Microsoft Edge WebView2的资料请关注我们其它相关文章!
C#设置WebBrowser使用Edge内核
1. 问题描述
用C#写了一个小工具, 需要显示网页上的内容, 但WebBrowser使用的是IE内核, 不能很好的展示网页
2. 解决方法
通过一些尝试, 在巧合之下找出了一种方法, 成功的让WebBrowser用上了Edge内核, 先上图
WebBrowser使用Edge内核
上代码
/// <summary>
/// 修改注册表信息使WebBrowser使用指定版本IE内核
/// </summary>
public static void SetFeatures(UInt32 ieMode) {
if (LicenseManager.UsageMode != LicenseUsageMode.Runtime) {
throw new ApplicationException();
}
//获取程序及名称
string appName = System.IO.Path.GetFileName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);
string featureControlRegKey = "HKEY_CURRENT_USER\\Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\";
//设置浏览器对应用程序(appName)以什么模式(ieMode)运行
Registry.SetValue(featureControlRegKey + "FEATURE_BROWSER_EMULATION", appName, ieMode, RegistryValueKind.DWord);
//不晓得设置有什么用
Registry.SetValue(featureControlRegKey + "FEATURE_ENABLE_CLIPCHILDREN_OPTIMIZATION", appName, 1, RegistryValueKind.DWord);
}
这个函数是网上复制的, 传入11000是IE11, 9000是IE9, 只不过当试着传入6000时, 理应是IE6, 可实际却是Edge, 这时进一步测试, 当传入除IE现有版本以外的一些数值时WebBrowser都使用Edge内核
设置注册表IE版本6000
3. 结论
将IE版本号设置为非IE版本的数值就能使用Edge内核
这个方法目前不知道原理, 并且也没有测试过稳定性, 以上内容仅供参考
使用C#调用Edge浏览器内核控件来访问网站
1.框架设置:
2.添加引用 Microsoft.Toolkit.Forms.UI.Controls.WebView
3. 拖控件(或者直接写代码也可以)
4.访问网页:
c# WebBrowser控制台输出执行js后的网页内容
还是处理视频下载所相关的问题。
有些网站,它的页面代码是由页面加载后js动态生成,那么其原始的html便不能用。页面渲染后的代码,是我们需要的
c#中,我用WebBrowser这个控件处理。设置项目类型为控制台程序,加Form承载WebBrowser实现。
记录代码以做备忘:
using System;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;
namespace crpj
{
[ComVisible(true)]
public class Form : System.Windows.Forms.Form
{
protected override void SetVisibleCore(bool value)
{
base.SetVisibleCore(false);
}
public string GetHtmlCode(string url)
{
using (var wc = new WebClient())
{
wc.Encoding = Encoding.UTF8;
return wc.DownloadString(url);
}
}
}
class Program
{
private static Timer tmrGet = new Timer();
private static Timer tmrExit = new Timer();
private static WebBrowser browser = new WebBrowser();
//延时获取?
private static int delay = 0;
//js注入脚本
private static string jsCode;
//禁止网页跳转声音
const int FEATURE_DISABLE_NAVIGATION_SOUNDS = 21;
const int SET_FEATURE_ON_PROCESS = 0x00000002;
[DllImport("urlmon.dll")]
[PreserveSig]
[return: MarshalAs(UnmanagedType.Error)]
static extern int CoInternetSetFeatureEnabled(
int FeatureEntry,
[MarshalAs(UnmanagedType.U4)] int dwFlags,
bool fEnable);
/// <summary>
/// 应用程序的主入口点。
/// </summary>
/// 参数列表:url delay jscode
[STAThread]
static void Main(string[] args)
{
if (args.Length == 0)
{
Console.WriteLine("error: You must provide at least one URL.");
return;
}
CoInternetSetFeatureEnabled(
FEATURE_DISABLE_NAVIGATION_SOUNDS,
SET_FEATURE_ON_PROCESS,
true);
ChackAndSetBrowserEmulation();
var form = new Form();
form.Controls.Add(browser);
browser.ObjectForScripting = form;
browser.ScriptErrorsSuppressed = true;
browser.DocumentCompleted += browser_DocumentCompleted;
browser.Navigate(args[0]);
if (args.Length > 1)
delay = int.Parse(args[1]);
if (args.Length > 2)
jsCode = args[2];
//因为页面有时需加载js初始化等操作,延时获取其页面内容
tmrGet.Tick += new EventHandler(tmrGet_Tick);
if (delay > 0)
tmrGet.Interval = delay;
//有些网页不触发complete事件,或者时间很长,此定时器做判断,以60秒为界,自结束
tmrExit.Tick += new EventHandler(tmrExit_Tick);
tmrExit.Interval = 90000;
tmrExit.Start();
Application.Run(form);
}
static void tmrExit_Tick(object sender, EventArgs e)
{
OutputHtml();
}
//WebBrowser以IE11版本做页面渲染
static void ChackAndSetBrowserEmulation()
{
try
{
string keyName = @"SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION";
using (var key = Registry.CurrentUser.OpenSubKey(keyName, true))
{
string valueName = Path.GetFileName(Application.ExecutablePath);
if (key.GetValue(valueName) == null)
key.SetValue(valueName, 11001);
}
}
catch
{
}
}
static void tmrGet_Tick(object sender, EventArgs e)
{
tmrGet.Stop();
OutputHtml();
}
static void OutputHtml()
{
tmrExit.Stop();
//避免韩文等乱码
Console.OutputEncoding = Encoding.UTF8;
//browser.DocumentText取不到执行js之后的body文件
string html = browser.Document.GetElementsByTagName("html")[0].OuterHtml;
Console.Write(html);
Application.Exit();
}
static void ExecJS(string jsCode)
{
var script = browser.Document.CreateElement("script");
script.SetAttribute("type", "text/javascript");
script.SetAttribute("text", "function _func() {" + jsCode + "}");
browser.Document.Body.AppendChild(script);
browser.Document.InvokeScript("_func");
}
static void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (browser.ReadyState == WebBrowserReadyState.Complete && e.Url == browser.Url)
{
//是否需要js注入?
if (!string.IsNullOrEmpty(jsCode))
{
ExecJS(jsCode);
System.Threading.Thread.Sleep(500);
}
if (delay == 0)
OutputHtml();
else
tmrGet.Start();
}
}
}
}
如此处理,可能得到所需要的html代码。
其在控制台输出图示效果
并基于此思路,设计进程输出管理器:
internal class ProcessOutputMgr
{
private static object syncObj = new Object();
private Process process = new Process();
private StringBuilder allData = new StringBuilder();
private bool exitedCalled = false;
public ProcessMgr(string fileName, string args)
{
var startInfo = new ProcessStartInfo(fileName);
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = args;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true; //crpj皆以utf-8输出,避免乱码 startInfo.StandardOutputEncoding = Encoding.UTF8;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
process.StartInfo = startInfo;
process.EnableRaisingEvents = true; //一定要有这个才能触发Exited 事件
process.Exited += process_Exited;
process.OutputDataReceived += process_OutputDataReceived;
process.ErrorDataReceived += process_ErrorDataReceived;
}
public event DataReceivedEventHandler OutputDataReceived;
public event DataReceivedEventHandler ErrorDataReceived;
public event Action<string> AllDataReceived;
public bool Start()
{
bool result = process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
return result;
}
public void WaitForExit()
{
process.WaitForExit();
}
public bool WaitForExit(int milliseconds)
{
return process.WaitForExit(milliseconds);
}
private void process_Exited(object sender, EventArgs e)
{
if (!this.exitedCalled && this.allData.Length != 0)
{
this.exitedCalled = true;
var handler = AllDataReceived;
if (handler != null)
handler(this.allData.ToString());
}
}
private void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
lock (syncObj)
{
var handler = OutputDataReceived;
if (handler != null)
handler(sender, e);
if (e.Data != null)
this.allData.AppendLine(e.Data);
else
{
var process = sender as Process;
if (process.HasExited && !this.exitedCalled)
{
this.exitedCalled = true;
if (AllDataReceived != null)
AllDataReceived(this.addData.ToString());
}
}
}
}
private void process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
lock (syncObj)
{
var handler = ErrorDataReceived;
if (handler != null)
handler(sender, e);
}
}
}
用WebBrowser获取JS动态加载以后的页面代码并保存图片
上一篇:MyCat使用技术收集