最近两年没有在春节回家过年了,主要是票太难买,虽然以前写了一个12306“无声购票弹窗”工具,解决了抢票问题,可是全家老少一块儿回去仍是很累,干脆就在北京过年了。这两天忽然有一个朋友问我你以前的抢票工具还能用不,我让他试试,他说能够,因而我以为这样一个小工具竟然还有人继续使用啊,既然有人用我就继续把他作好点,让你们过年抢票更“安心”!html
以前的抢票工具是基于IEBrowser控件作的,不用说你们都知道这个控件在不一样的Windows系统上表现各异,由于它主要依赖于IE内核,坑爹的是它有时候尚未直接使用IE效果好,因此使用我这个抢票工具总有不顺收的地方,好比一些显示问题,提交订单后没法直接支付问题等。看到朋友介绍说CefSharp控件不错,因而决定试试,没想到出了网上介绍的坑,还有些其它的坑没有人写过,这里写出来给你们作一个参考。git
最新版的CefSharp要求.NET应用程序至少支持 .NET 4.5.2以上,而我此次要整合的工具程序仍是 .NET 4.0的,照作相关资料去下载了一个以前的版本,结果在JS没法调用VB.NET写的方法,而它去能够在X64模式下调用C#写的方法。无法只好升级到CefSharp 57.0.0 ,才解决了这个问题。github
JS调用VB.NET的代码以下:sql
VB.NET代码:数据库
Public Class TicketNotify Dim owerForm As Form Public Sub New(ByVal owner As Form) Me.owerForm = owner End Sub Public Sub MyNotify() Dim target As frm12306Ticket = Me.owerForm target.FoundTickt = True ' target.Notify() End Sub End Class
将这个.NET类注册到Cef浏览器里面去:windows
Dim WithEvents WebBrowser1 As CefSharp.WinForms.ChromiumWebBrowser Me.WebBrowser1 = New CefSharp.WinForms.ChromiumWebBrowser(Me.ticketUrl) Me.WebBrowser1.RegisterJsObject("jsObj", New TicketNotify(Me), Nothing)
而后,将一段调用这个.NET方法的JS函数注入到Cef浏览器内:浏览器
Private Sub WebBrowser1_FrameLoadEnd(sender As Object, e As FrameLoadEndEventArgs) Handles WebBrowser1.FrameLoadEnd Dim js As String = <string> var divAlert=true; function checkHaveTicket() { var div = document.getElementById('autosubmitcheckticketinfo'); if (div) { if (div.style.display == 'block' || div.style.display == '') { //txtName.value = '有票了!!!'; jsObj.myNotify(); } } } </string> '下面两行代码效果同样 'Me.WebBrowser1.GetMainFrame().ExecuteJavaScriptAsync(js) Me.WebBrowser1.ExecuteScriptAsync(js) End Sub
这样,浏览器执行 jsObj.myNotify(); 这个方法就能够调用咱们的.NET对象的方法 MyNotify() 了。安全
PS:注意上面有一个代码 <string>...</string> ,这个是VB.NET独特的XML语句块,XML是VB.NET的一种数据类型,就像你自定义的类型同样,这里用来表示一个字符串,因此用它来表示多行字符串是最合适的了。
因为CefSharp版本问题,这个JS代码必须写到 浏览器控件的 FrameLoadEnd 事件中,可是以前查询到文章里面都说能够在 IsBrowserInitializedChanged 事件里面,如今是找不到的,但不报错,例以下面实际的代码说明:app
Private Sub WebBrowser1_IsBrowserInitializedChanged(sender As Object, e As IsBrowserInitializedChangedEventArgs) Handles WebBrowser1.IsBrowserInitializedChanged If e.IsBrowserInitialized Then '不能够在这里注册JS代码,新版CefSharp 找不到 '不能够在这里开启定时器,不然定时器的事件会在当前线程,也就是UI线程以外运行,相关UI访问代码会发生“线程间操做无效”的异常 'Me.Timer1.Start() End If End Sub
我在公司的Windows 10系统下CefSharp运行正常,可是回家在Windows 8.1系统上,发现Cef浏览器老是不能填充满窗口,只有一半大小,可是滚动条位置却能鼓动,滚动的时候会看到闪屏,同时页面上控件的点击位置也是错位的,须要点击下才能回复页面大小,但很快又变小了。查了下资料,说能够经过程序集清单设置文件进行设置:框架
<?xml version="1.0" encoding="utf-8"?> <asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> <security> <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> <!-- UAC 清单选项 若是但愿更改 Windows 用户账户控制级别,请用如下节点之一替换 requestedExecutionLevel 节点。 <requestedExecutionLevel level="asInvoker" uiAccess="false" /> <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> <requestedExecutionLevel level="highestAvailable" uiAccess="false" /> 若是您但愿利用文件和注册表虚拟化提供 向后兼容性,请删除 requestedExecutionLevel 节点。 --> <requestedExecutionLevel level="asInvoker" uiAccess="false" /> </requestedPrivileges> </security> </trustInfo> <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <application> <!-- 此应用程序设计使用的全部 Windows 版本的列表。 Windows 将会自动选择最兼容的环境。--> <!-- 若是应用程序设计为使用 Windows Vista,请取消注释如下 supportedOS 节点--> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"></supportedOS> <!-- 若是应用程序设计使用 Windows 7,请取消注释如下 supportedOS 节点--> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> <!-- 若是应用程序设计为使用 Windows 8,请取消注释如下 supportedOS 节点--> <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"></supportedOS> <!-- 若是应用程序设计为使用 Windows 8.1,请取消对如下 supportedOS 节点的注释--> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> </application> </compatibility> <!--<application xmlns="urn:schemas-microsoft-com:asm.v3"> <windowsSettings> <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware> </windowsSettings> </application>--> </asmv1:assembly>
结果无效,后来看到可能没有禁用GPU有关,因而作下设置:
Dim setting As CefSettings = New CefSettings() With setting .Locale = "zh-CN" .AcceptLanguageList = "zh-CN" .MultiThreadedMessageLoop = True End With Dim osVersion = Environment.OSVersion '//Disable GPU for Windows 7 ,8,8.1 If osVersion.Version.Major = 6 Then '// Disable GPU in WPF and Offscreen examples until #1634 has been resolved setting.CefCommandLineArgs.Add("disable-gpu", "1") End If CefSharp.Cef.Initialize(setting)
通过这样的设置后,终于显示正常了。
小工具是经过定时器不断监控页面有没有出现特定的标记来表示有票的,就是上面注入的JS代码中的 checkHaveTicket 函数。以前是在 CefSharp控件的 IsBrowserInitializedChanged 事件中处理的,结果发现运行时偶发错误,并且是Win 10不报错可是Win 8.1报错:
相关UI访问代码会发生“线程间操做无效”的异常
推测是CefSharp控件的这些事件可能不必定运行在UI线程,在非UI线程启动定时器那么定时器的“定时事件”也不在UI线程了,因此报错。
本次更新增长了“声音通知”功能,发现有票后会不断播放音乐提示,以方便你不在电脑跟前也能知道。
这样不论你是否在电脑跟前而且不想被刷票问题打扰,这就是本工具最大的优点了,第一时间弹窗通知,不用时时刻刻去看。
最后关于安全问题,既然开源了,就不会有什么偷窥您隐私问题的可能性了,能够放心使用!
其它问题就没有了,处理方式跟以前的弹窗工具同样,代码我已经签入到了SOD的Github代码库中,地址以下:https://github.com/znlgis/sod
下面附带一个运行测试效果图:
下面是打开12306自动刷票功能的效果图:
若是有问题,或者想获取编译好的程序包,请加QQ群:18215717 ,加群请注明暗号:博客园看到12306刷票工具
稍后我会放到CSDN下载频道,请你们注意本篇博客文章的更新。
PS:
“安心刷票弹窗通知工具”如今集成到了 "PDF.NET集成开发工具"里面,因此这意味着你既能够用它来作一个轻量级的多种数据库的查询客户端,也能够作一个简单的谷歌浏览器。
注意:
虽然“SOD框架”是基于LGPL协议发布的开源软件,可是集成开发工具属于GPL开源协议,你能够自由的免费的使用本软件,但不可使用这个工具的源码用做商业用途。SOD框架的其它部分源码不在此限制范围。
详细问题请看PDF.NET框架官网 http://www.pwmis.com/sqlmap ,若是有问题请和咱们联系。