C#操作IE瀏覽器

轉自:http://www.cnblogs.com/kissdodog/p/3725774.html


  最近的一個B/S系統中,用到了指模錄入,當用戶按了手指摸之後,要在IE瀏覽器的一個文本框上顯示用戶的姓名。由於要監控指模機的輸入,因此客戶端需要裝一個.net控制檯程序,通過此控制檯程序監控指模機。這個沒辦法。這個.net控制檯程序裝在公司前臺的電腦上就OK了。然後通過局域網與指模機相聯,當用戶按手指摸並且驗證通過之後,從指模機讀取用戶的姓名,然後檢測當前瀏覽器是否有打開系統上的某個頁面。如果有,則將姓名輸入到IE瀏覽器的響應文本框。

  這裏用到的最麻煩的一個東東就是C#操作IE瀏覽器。之前太孤陋寡聞,一開始的想法是控制檯程序發送上遠程服務器,然後頁面AJAX輪詢,但是耗用比較大的資源。下面主要通過com組件實現控制檯程序操作IE。

  1、首先,需要添加com組件的引用

  • 加入對Microsoft Internet Controls的引用;
  • 加入對Microsoft HTML Object Library的引用;(其實就是的mshtml)  

   2、打開一個新Tab並打開指定地址

複製代碼
    //新建一個Tab,然後打開指定地址
    SHDocVw.ShellWindows shellWindows = new SHDocVw.ShellWindowsClass();
    object objFlags = 1;
    object objTargetFrameName = "";
    object objPostData = "";
    object objHeaders = "";
    SHDocVw.InternetExplorer webBrowser1= (SHDocVw.InternetExplorer)shellWindows.Item(shellWindows.Count-1);
    webBrowser1.Navigate("http://www.baidu.com", ref objFlags, ref objTargetFrameName, ref objPostData, ref objHeaders);
複製代碼

  如果需要手動啓動IE瀏覽器進程的話,可以使用:

    Process.Start("iexplore.exe");  //直接打開IE瀏覽器(打開默認首頁)
    Process.Start("iexplore.exe","http://www.cnblogs.com/kissdodog");  //直接打開IE瀏覽器,打開指定頁

  3、操作js

  下面,通過操作js實現如下效果:往百度搜索框裏面輸入"劉德華"並點擊搜索。

複製代碼
    //遍歷所有選項卡
    foreach (SHDocVw.InternetExplorer Browser in shellWindows)
    {
        if (Browser.LocationURL.Contains("www.baidu.com"))
        {
            //通過操作js點擊按鈕
            if (Browser.Document is HTMLDocumentClass)
            {
                HTMLDocumentClass doc2 = Browser.Document as HTMLDocumentClass;
                HTMLScriptElement script = (HTMLScriptElement)doc2.createElement("script");
                //script.text = "alert(123);";
                //恰好百度用了jQuery
                script.text = "$(\"#kw1\").val('劉德華'); $(\"#su1\").click();";
                HTMLBodyClass body = doc2.body as HTMLBodyClass;
                body.appendChild((IHTMLDOMNode)script);
            }
        }
    }
複製代碼

  4、C#直接通過DOM操作IE

  C#直接通過Dom操作IE

複製代碼
    SHDocVw.ShellWindows shellWindows = new SHDocVw.ShellWindowsClass();
    //遍歷所有選項卡
    foreach (SHDocVw.InternetExplorer Browser in shellWindows)
    {
        if (Browser.LocationURL.Contains("www.baidu.com"))
        {
            mshtml.IHTMLDocument2 doc2 = (mshtml.IHTMLDocument2)Browser.Document;
            mshtml.IHTMLElementCollection inputs = (mshtml.IHTMLElementCollection)doc2.all.tags("INPUT");
            mshtml.HTMLInputElement input1 = (mshtml.HTMLInputElement)inputs.item("kw1", 0);
            input1.value = "劉德華";
            mshtml.IHTMLElement element2 = (mshtml.IHTMLElement)inputs.item("su1", 0);
            element2.click();
        }
    }
複製代碼

  5、在裏面操作IFrame

  操作IFrame是一個比較麻煩的操作,很多方式都不能實現,目前唯一的辦法是通過在頁面上執行一段js實現操作IFrame(希望有人能告訴我)。

  2014年8月5日  熱死人了

  特別說明:上個星期去客戶電腦上部署的時候,mshtml.dll無論如何都調用不成功,但是在客戶機子上裝了VS之後,又不用改代碼又成功了。首先提示找不到mshtml.dll 7.0.33。然後網上找到一堆方法,把複製都本地設置爲True了。然後又這又那都不行。嘗試瞭如下方法之後好像OK了,特別做記錄。

  mshtml.dll 文件沒有被 IE 正確關聯,可運行命令使其再次關聯。關聯方法較簡單,點擊“開始”菜單裏的“運行”,在空框處填入 regsvr32 /u mshtml.dll 命令先卸載關聯,如果卸載成功,會提示“ mshtml.dll 中的 DllUnregisterServer 成功。”,然後再填入 regsvr32 mshtml.dll 命令進行關聯,如果關聯成功,會提示“ mshtml.dll 中的 DllRegisterServer 成功。”,最後重啓電腦即可。此法最好在安全模式下進行,以防系統正在使用 mshtml.dll 文件而導致卸載和關聯失敗。此法我也試過,對我無效,希望對其它網友有用。

  如果提示找不到dll文件,那麼將C:\Program Files\Microsoft.NET\Primary Interop Assemblies\Microsoft.mshtml.dll複製到C:\Windows\assembly

  System.NotImplementedException: 未實現該方法或操作。
  可以嘗試在 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727目錄下運行RegAsm.exe
  C:\Program Files\Microsoft.NET\Primary Interop Assemblies\Microsoft.mshtml.dll 
  mshtml.dll /registered

  最後把代碼改爲:

複製代碼
    string sName = "IE測試";
    ShellWindows shellWindows = new ShellWindowsClass();
    foreach (InternetExplorer Browser in shellWindows)
    {
        if (Browser.Document is HTMLDocument)
        {
            HTMLDocument doc2 = Browser.Document as HTMLDocument;
            HTMLScriptElement script = (HTMLScriptElement)doc2.createElement("script");
            if (sName.Contains("\0"))
            {
                sName = sName.Substring(0, sName.IndexOf("\0"));
            }
            script.text = string.Format("alert(\"彈出此對話框則正常!\")", sName);
            HTMLBody body = doc2.body as HTMLBody;
            if (body == null)
            {
                MessageBox.Show("果然是Body爲NULL");
            }
            else
            {
                body.appendChild((IHTMLDOMNode)script);
            }
        }
    }
複製代碼

  注意,區別在於把類變了 : HTMLDocumentClass => HTMLDocument,HTMLBodyClass => HTMLBody。

  這樣就在客戶機子上不用裝VS都可以了,至於爲什麼這麼改就可以,暫時不得而知,最近實在忙。沒時間深究。

  解決:COM 組件的調用返回了錯誤 HRESULT E_FAIL

  這個東西總在Browser.Document時發生,經過查看,發現Document的狀態始終都爲未加載完畢時(實際上已加載完畢,客戶機子IE8 XP)就會出現此錯誤。

  不要用這個屬性了,通過LocalhostUrl屬性判斷是否這個頁面(就是說盡量避開這個Document,有無解Bug)。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章