基于CefSharp开发浏览器(一)项目搭建
CefSharp中文帮助文档
“public partial class Form1 : Form”如何解释:
public 表示类的访问级别 公开 partial 表示部分类 就是说这些代码只是类的一部分 (还有另一部分在其他地方) Form1 类名
“:”冒号在这里表示继承 Form 也是类名(此处表示基类)
公共 大 巴士:汽车
公共、大都是修饰巴士的。
巴士的基类是汽车。
C#类(一):类和对象--static静态对象
C# Action<T> 委托
委托和事件(四)——简单传值
这里使用Action,直接传值,
功能是:form1打开form2时,把值传过去
Form1
Form2
1 使用委托:
Form1代码:
private void button1_Click(object sender, EventArgs e) { //在窗体Form1,打开窗体Form2 Form2 f2 = new Form2(); f2.Show(); f2.act1(textBox1.Text,textBox2.Text); }
Form2代码:
public Action<string, string> act1; private void Form2_Load(object sender, EventArgs e) { act1 = (x, y) => { textBox1.Text = x; textBox2.Text = y; }; }
2 使用事件
Form1
public event Action<string, string> act1; private void button1_Click(object sender, EventArgs e) { Form2 f2 = new Form2(); f2.Show(); act1 = f2.Test; act1(textBox1.Text,textBox2.Text); }
Form2
public Action<string, string> act1; private void Form2_Load(object sender, EventArgs e) { act1 = (x, y) => { textBox1.Text = x; textBox2.Text = y; }; }
转载于:https://www.cnblogs.com/hanjun0612/p/10796250.html
C#事件的四种写法Delegate
delegate委托,常用于事件:
第一种:常规事件
Button1.click+=Button1_Click;
private void Button1_Click(object sender,EventArgs e){
}
第二种:lambda表达式
Button1.Click+=(s,e)=>{
};
第三种:
Button1.Click+=delegate(object sender,EventArgs e) {
};
第四种:匿名事件处理
Button1.Click+=delegate {
};
c#中“?”的几种用法
1、可空类型修饰符(?),如:
int? x = null;//可空类型默认值都是null,而值类型如int默认值为0、bool默认值为false等
bool? result = true;
2、三元运算符(?😃,如:bool f=false; return f==true?1:0;如果f为true则返回1,否则返回0
3、 空合并运算符(??)
如:a??b 当a为null时则返回b,a不为null时则返回a本身
“a??b??c”的形式按“a??(b??c)”计算
4、NULL检查运算符(?.)
fileInfo?.Close() 当fileInfo不为null是执行Close方法
DateTime? birthday= personList?.FirstOrDefault()?.Birthday;
C#中的委托(delegate)
什么是委托?
委托(delegate)是一种托管方法的数据结构,它是一种引用类型,是对方法的引用。如果说int,string等是对数据类型的定义,那么委托就类似于对“方法类型”的定义,声明一个委托,就是声明一种方法签名,只要是和声明委托方法签名相同的方法,都可以被委托实例托管。那为什么叫委托呢,这个名字似乎看似和它的职责不相干,但其实这是很“面向对象”的称呼,一个方法自己办不到的事情,去让另一个方法帮他做,这两者之间的关系不就是委托吗,这样的抽象关系不就是面向对象的一部分吗。
如何声明一个委托?
委托的关键字是delegate ,由它开头,后边接返回值类型,委托名称以及参数具体如下:
delegate 返回值类型 委托名称 (方法参数)
Action<T>和Func<T,T>中的“T”的含义
“T”is Type(类型)
Action<T>
is exactly the same as delegate void ... (T t)
Func<T>
is exactly the same as delegate T ... ()
Func<T,TResult> is exactly the same as delegat T ...(TResult tresult)
Action and Func are simply convenience delegates that have been defined in the 3.5 clr.
Action, Func and lambdas are all just syntactical sugar and convenience for using delegates.
There is nothing magic about them. Several people have written simple 2.0 addon libraries to add this functionality to 2.0 code.
C# 开启、关闭新线程示例
1.添加头文件
using System;
using System.Threading;
2.在你需要开启线程的地方,调用下面函数开启线程
//创建无参的线程
Thread thread1 = new Thread(new ThreadStart(Thread1)); //Thread1是你新线程的函数
thread1.Start(); //调用Start方法执行线程
3.编写你的新线程函数,在该函数里编写你需要执行的代码逻辑,当你代码启用线程时会执行该函数
/// <summary>
/// 创建无参的方法,新开的线程
/// </summary>
void Thread1()
{
//编写新线程要执行的代码逻辑
}
4.在你需要关闭线程的地方调用下面函数关闭线程,Abort() 方法用于销毁线程
//thread1 是你上面创建线程的时候的线程名字,注意该函数要跟你创建的线程在同一个有效范围
thread1.Abort();
5.关闭整个窗体程序时,关闭所有该程序的线程
// 只是关闭当前窗口,若不是主窗体的话,是无法退出程序的,另外若有托管线程(非主线程),也无法干净地退出;
this.Close();
// 强制所有消息中止,退出所有的窗体,但是若有托管线程(非主线程),也无法干净地退出;
Application.Exit();
//强制中止调用线程上的所有消息,同样面临其它线程无法正确退出的问题;
Application.ExitThread();
//这是最彻底的退出方式,不管什么线程都被强制退出,把程序结束的很干净。
System.Environment.Exit(0);
CefSharp中文帮助文档
C#使用CefSharp控件实现爬虫
CefSharp——无所不能的数据抓取利器
CefSharp——Chromium Embedded Framework,用.net编写的浏览器包
嵌入浏览器的实现:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
ChromiumWebBrowser WebBrowser;
private void Form1_Load(object sender, EventArgs e)
{
var settings = new CefSettings()
{
UserAgent = "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Mobile Safari/537.36",
};
//Perform dependency check to make sure all relevant resources are in our output directory.
Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);
// cefsharp提供的浏览器控件,一般用它充满窗口就搞定了
WebBrowser = new ChromiumWebBrowser("http://www.163.com")
{
// 填充整个父控件
Dock = DockStyle.Fill
};
WebBrowser.FrameLoadEnd += new EventHandler<FrameLoadEndEventArgs>(FrameEndFunc);
// 添加到窗口的控件列表中
this.panel1.Controls.Add(WebBrowser);
}
private void FrameEndFunc(object sender, FrameLoadEndEventArgs e)
{
MessageBox.Show("加载完毕");
this.BeginInvoke(new Action(() =>
{
String html = WebBrowser.GetSourceAsync().Result;
richTextBox1.Text = html;
}));
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
// 结束时要销毁
Cef.Shutdown();
}
}
}
ChromiumWebBrowser实例的FrameLoadEnd页面加载完成事件
如何使用vs对象浏览器看懂一个dll的所有对象:
C#winform中使用Cef的ChromiumWebBrowser内嵌谷歌内核,调用前端js方法
1、在winform中调用js方法:
--调js中的方法无 入参形式
webBrowser1.ExecuteJavascript("logout()");
webBrowser1.ExecuteJavascript("alert('Hello!')");
--调js中的方法给js中的变量赋值操作
webBrowser1.ExecuteJavascript("jsFunction('var1','var2')");
webBrowser1.ExecuteJavascript("var3='hello word'");//调js中的方法,有 入参情况
谷歌浏览器获取网页元素的xpath
JavaScript实用手册_aiguangyuan的博客-优快云博客_javascript 开发手册
Node.js安装教程(Windows版本)
安装网址:Download | Node.js
选择windows installer:
快速下载Visual Studio Code
打开Visual Studio Code的官网。
Visual Studio Code - Code Editing. Redefined
因为一些众所周知的原因,在国内下载Visual Studio Code的速度比较慢,所以我们需要一些方法来加快Visual Studio Code的下载。
直接开下
不废话了,将官方的下载地址中的类似【az764295.vo.msecnd.net 】的地址替换为:【vscode.cdn.azure.cn】即可。
黑框右上角可以一键复制。
vscode.cdn.azure.cn
:nth-child(n)选择器的作用是匹配属于其父元素的第N个子元素,不论元素的类型
js的querySelector()、querySelectorAll()方法:
querySelector()
方法来说,只会返回匹配的第一个元素结点。
querySelectorAll()
会把匹配的所有元素节点封装成一个数组返回
.innerHTML与.innerText二者的区别:
前者是当前标签的内容中还有标签,连同标签一起显示;后者不显示标签只显示内容。
最近在处理拖动问题时,总算是深入探索了一下offsetParent的问题:
jsoffsetParent探索 简单
先看看定义官方定义:
offsetParent returns a reference to the object which is the closest (nearest in the containment hierarchy) positioned containing element. If the element is non-positioned, the root element (html in standards compliant mode; body in quirks rendering mode) is the offsetParent. offsetParent returns null when the element has style.display set to "none".
简单解释就是:
1. 假设结果节点的display不是none:
返回结果是一个dom节点,并且该节点具有定位属性(absolute, relative, fixed(ie7+)),如果父节点都不满足条件,则追溯到body(ie6、7在standard模式下返回html,ie在怪异模式下返回body)
2. 如果display是none:
在ie6、7(标准模式)(ie6、7、8怪异模式下返回)下返回满足上述条件的父节点;其他浏览器都返回undefined
JavaScript push() 方法
实例
数组中添加新元素:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.push("Kiwi")
fruits 结果输出:
Banana,Orange,Apple,Mango,Kiwi
定义和用法
push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。
注意: 新元素将添加在数组的末尾。
注意: 此方法改变数组的长度。
提示: 在数组起始位置添加元素请使用 unshift() 方法。
浏览器支持
所有主要浏览器都支持push()。
语法
array.push(item1, item2, ..., itemX)
参数值
参数 | 描述 |
---|---|
item1, item2, ..., itemX | 必需。要添加到数组的元素。 |
实例
添加一个以上元素
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.push("Kiwi","Lemon","Pineapple")
以上实例将输出
Banana,Orange,Apple,Mango,Kiwi,Lemon,Pineapple
CefSharp EvaluateScriptAsync执行js 返回对象、页面元素Node、对象数组
正常情况下,返回单值是没有问题的,但是返回对象,Node这种对象,要想让C#正常接收 js 就得特殊处理一下了:
这里webview就是ChromiumWebBrowser浏览器对象
返回对象
webview.EvaluateScriptAsync("new Object({'name':'zhangsan','age':10})").ContinueWith(new Action<Task<JavascriptResponse>>((respA) => { JavascriptResponse resp = respA.Result; //respObj此时有两个属性: name、age dynamic respObj = resp.Result; Console.WriteLine(respObj.name + " " + respObj.age); }));
JS返回的对象直接使用 {'name':'zhangsan','age':10} 是不行的,需要用Object对象包起来由于见识太短,不知道什么原因,非常欢迎各位前辈指教,非常感谢!
数组对象
返回数组对象也一样,数组中不能直接使用{xx:xx}形式, 还是需要通过Object返回
webview.EvaluateScriptAsync("[new Object({'name':'zhangsan','age':10})]").ContinueWith(new Action<Task<JavascriptResponse>>((respA) => { JavascriptResponse resp = respA.Result; List<dynamic> respObj = (List<dynamic>)resp.Result; Console.WriteLine(respObj[0].name ); }));
页面对象
页面元素对象有点特殊,直接使用new Object(对象) 是不行的,用到Node元素中哪个属性,需要手动添加:
<a href="http://www.baidu.com" id = "a">A</a> <a href="http://i.cnblogs.com">B</a>
单个Node对象时,暂时没找到好的转换成Object办法,如果各位前辈有更好的处理办法,请留言!
比如此处用到了A标签的href属性:
//获取A标签的href属性 webview.EvaluateScriptAsync("new Object({href: document.getElementById('a').href})").ContinueWith(new Action<Task<JavascriptResponse>>((respA) => { JavascriptResponse resp = respA.Result; Console.WriteLine(resp.Result.href); }));
多个Node对象时,通过js的Array.from把一个个Node对象拼成了Object对象:
//获取多个A标签href属性 webview.EvaluateScriptAsync("Array.from(document.querySelectorAll('a'), item => new Object({ href: item.href }) );").ContinueWith(new Action<Task<JavascriptResponse>>((respA) => { JavascriptResponse resp = respA.Result; List<dynamic> respObj = (List<dynamic>)resp.Result; Console.WriteLine(respObj[0].href); }));
public async Task<string> onJs(string js)
{
if (this != null)
{
string result = null;
DateTime starttime = DateTime.Now;
//int timeout = 30;
for (int i = 0; i < this.GetBrowser().GetFrameNames().Count; i++)
{
var frm = this.GetBrowser().GetFrame(this.GetBrowser().GetFrameNames()[i]);
var task01 = this.GetBrowser().GetFrame(this.GetBrowser().GetFrameNames()[i]).EvaluateScriptAsync(js);
task01.ContinueWith(t =>
{
if (!t.IsFaulted)
{
var response = t.Result;
if (response.Success == true)
{
if (response.Result != null)
{
if (response?.Result != null && response.Result.GetType().Name == "ExpandoObject")
{
result = Newtonsoft.Json.JsonConvert.SerializeObject(response.Result);
;
}
else
{
string resultStr = response.Result.ToString();
result = resultStr;
}
}
}
}
}).Wait();
if (string.IsNullOrEmpty(result) == false)
{
break;
}
}//while ((DateTime.Now - starttime).TotalSeconds > timeout || string.IsNullOrEmpty(result)) { };
return result;
}
return null;
}