2011-09-07 27 views
5

這是在.net 3.5 winform上運行的Web單點登錄代碼。只要ie8只有一個選項卡打開,代碼可以正常運行ie6或ie8。問題是,如果用戶打開一個新選項卡(選項卡2,3等)並導航到一個網站(組織內部的Web表單),下面的代碼將被執行,但是COM自動化對象將返回HTMLDocument對於第一個選項卡(選項卡1),即使選項卡2是活動選項卡。我無法在任何地方的InternetExplorer或HTMLDocument類中找到任何IE選項卡引用。實際上,IE COM自動化文檔中的任何地方都沒有IE標籤相關的文檔。IE瀏覽器8的InternetExplorer COM對象忽略活動選項卡

AutoResetEvent ie2_NavigateCompleteAutoReset; 

    /// <summary> 
    /// Given the handle of an Internet Explorer instance, this method performs single sign on to 
    /// several known web login forms. 
    /// </summary> 
    /// <param name="iEFramHandle"></param> 
    private void WebFormSignOn(int iEFramHandle) 
    { 
     foreach (SHDocVw.InternetExplorer ie2 in new SHDocVw.ShellWindows()) 
     { 
      if (ie2.HWND == iEFramHandle) 
      { 
       while (true) 
       { 
        Thread.Sleep(100); 
        if (ie2.ReadyState == SHDocVw.tagREADYSTATE.READYSTATE_COMPLETE) 
        { 
         try 
         { 
          mshtml.HTMLDocument doc = (mshtml.HTMLDocument)ie2.Document; 
          ie2.NavigateComplete2 += new SHDocVw.DWebBrowserEvents2_NavigateComplete2EventHandler(ie2_NavigateComplete2); 
          ie2_NavigateCompleteAutoReset = new AutoResetEvent(false); 

          /*Find the username element and enter the user's username*/ 
          mshtml.HTMLInputElement userID = (mshtml.HTMLInputElement)doc.all.item("username", 0); 
          userID.value = Globals.Username; 

          /*Find the password element and enter the user's password*/ 
          mshtml.HTMLInputElement pwd = (mshtml.HTMLInputElement)doc.all.item("password", 0); 
          pwd.value = Globals.GetAppName(); 

          /*Find the submit element/button and click it*/ 
          mshtml.HTMLInputElement btnsubmit = (mshtml.HTMLInputElement)doc.all.item("submit", 0); 
          btnsubmit.click(); 

          /*Wait up to 5 seconds for the form submit to complete. 
          This is to prevent this method from being called multiple times 
          while waiting for the form submit and subsequent navigation from completing.*/ 
          ie2_NavigateCompleteAutoReset.WaitOne(5000); 
          return; 
         } 
         catch (Exception err) 
         { 
          Logger.Log(err.ToString(), Logger.StatusFlag.Error, this.ToString(), "WebFormSignOn"); 
          return; 
         } 
         finally 
         { 
          /*Remove the event handler*/ 
          ie2.NavigateComplete2 -= ie2_NavigateComplete2; 

         } 
        } 
       } 
      } 
     } 
    } 

    void ie2_NavigateComplete2(object pDisp, ref object URL) 
    { 
     ie2_NavigateCompleteAutoReset.Set(); 
    } 

回答

4

事實證明,IE 8中的每個選項卡都有自己的進程和句柄。在原始代碼中,我總是從第一個IEFrame獲取句柄。我修改了代碼(下面),現在它工作。改變是,代替只查找第一個IEFrame句柄,代碼還查找與觸發調用WebFormsSignOut的方法的url相匹配的LocationURL。

private void WebFormSignOn(int iEFramHandle,string addressBarText) 
{ 
    var shellWindows = new SHDocVw.ShellWindows(); 
    foreach (SHDocVw.InternetExplorer ie2 in shellWindows) 
    { 
     if (ie2.LocationURL==addressBarText) 
     { //rest of the code (see orignal post) 
3

Internet Explorer沒有任何公共選項卡API(除了允許您將導航定位到新的前景或背景選項卡外)。每個ActiveX控件或BHO分別加載到單個選項卡實例中。嘗試從ShellWindows集合中走下來通常不太可能工作,相反,您應該讓您的插件接觸其託管站點(例如IObjectWithSite :: SetSite將傳達此信息),這將允許您確定您的託管選項卡。