2011-09-07 10 views
5

Questo è il codice single sign on Web che viene eseguito su un winform .net 3.5. Il codice funziona bene per ie6 o ie8 fino a quando 8 ha solo una scheda aperta. Il problema è che se l'utente apre una nuova scheda (scheda 2,3, ecc.) E naviga verso un sito web (modulo web interno all'organizzazione) verrà eseguito il codice sottostante, ma l'oggetto di automazione COM restituirà HTMLDocument per la prima scheda (scheda 1) anche se la scheda 2 è la scheda attiva. Non riesco a trovare alcun riferimento alle schede IE nelle classi di InternetExplorer o HTMLDocument. In realtà, c'è molto poca documentazione relativa alla scheda IE anyherer nei documenti di automazione COM IE.Scheda attiva ignorata dall'oggetto InternetExplorer COM per IE 8

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(); 
    } 

risposta

4

Si scopre che ogni scheda in IE 8 ha il proprio processo e gestione. Nel codice originale ricevevo sempre l'handle dal primo IEFrame. Ho modificato il codice (sotto) e ora funziona. Il cambiamento è che invece di cercare solo il primo handle IEFrame, il codice cerca anche un LocationURL che corrisponda all'URL che ha attivato il metodo che chiama WebFormsSignOut.

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 non ha API scheda pubblici (oltre a permettere di indirizzare una navigazione a un nuovo primo piano o scheda di fondo). Ogni controllo ActiveX o BHO viene caricato individualmente in una singola istanza di tabulazione. Non è probabile che il tentativo di scendere dalla raccolta ShellWindows funzioni in generale, ma il tuo plug-in dovrebbe raggiungere il suo sito di hosting (ad es. IObjectWithSite :: SetSite trasmetterà queste informazioni) che ti consentirà di determinare la tua scheda di hosting.