碰到一個無比坑爹,外加蛋疼乳酸的問題。從昨天晚上發現bug,到今天下午解決問題,搞了大半天的時間。光是找問題就花了半天,解決問題的方法簡單,但是方案的形成也是無比糾結的過程。
背景:webbrowser獲取頁面上的驗證碼,然后解析驗證碼回寫到頁面。解析和回寫沒什么問題,問題主要在獲取頁面驗證碼上。
在網上搜索得到這么一段代碼:
IHTMLControlElement img = (IHTMLControlElement)webBrowser1.Document.Images["vcode_img"].DomElement; IHTMLControlRange range = (IHTMLControlRange)((HTMLBody)html.body).createControlRange(); range.add(img); range.execCommand("Copy", false, null); img = null; range = null; html = null; if (Clipboard.ContainsImage()) this.pictureBox1.Image = Clipboard.GetImage(); else MessageBox.Show("執行不成功"); Clipboard.Clear();
獲取驗證碼圖片的核心也在這里。復制圖片數據到內存,然后從剪貼板讀取到pictureBox控件。
圖片很順利的取出來了。
但是實際調用的時候,發現“時靈時不靈”,不時的會冒出“執行不成功”的彈框。
剛開始以為是線程運行順序導致的,加了一堆Thread.Sleep,發現毫無改善。
各種測試,毫無頭緒......
無意中發現某一次報錯時,頁面上選中了部分文字。難道是這里的問題?於是重點測試,每次選中文字之后,解析驗證碼,報錯。而沒有選中文字時,運行這部分代碼,安然通過。我X,這是什么狗血情況,問題居然出在頁面當前有選中文字上??郁悶吶》。。。。。
找到問題后,解決問題的方向就很明確了。在執行這段代碼之前,取消頁面選擇。
問題又來了,對於我這么一個沒搞過js、html的c#初級猿,怎么取消webbrowser頁面選擇文字還真是難到我了,試過很多方法,focus,select,moveStart,move...通通滴死啦死啦滴...
過程很坎坷,結果很簡潔。一句txtRange.execCommand("Unselect");搞定。
完整代碼:
var code = ""; var body = (mshtml.HTMLBodyClass)((mshtml.HTMLDocumentClass)wbsContent.Document.Window.Frames[0].Document.DomDocument).body; IHTMLControlElement img = (IHTMLControlElement)((mshtml.HTMLDocumentClass)wbsContent.Document.Window.Frames[0].Document.DomDocument).images.item("imgCode"); IHTMLControlRange range = (IHTMLControlRange)body.createControlRange(); IHTMLTxtRange txtRange = body.createTextRange(); txtRange.execCommand("Unselect"); range.add(img); range.execCommand("Copy"); img = null; range = null; if (Clipboard.ContainsImage()) { code = UnCodeBase.GetVarifyCodeFromWinWinTask((Bitmap)Clipboard.GetImage()); var txtVrf = (mshtml.HTMLInputElementClass)((mshtml.HTMLDocumentClass)wbsContent.Document.Window.Frames[0].Document.DomDocument).all.item("code"); txtVrf.setAttribute("value", code); return true; }
這是Frame的情況,相信沒有Frame的情況應該可以照着這個思路處理。
問題解決了的時候,還是很開心的,雖然還是覺得這個問題很讓人郁悶.
