最近兩年沒有在春節回家過年了,主要是票太難買,雖然以前寫了一個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 ,若是有問題請和咱們聯繫。