2011-09-07 7 views
5

Este es un código de inicio de sesión único en la web que se ejecuta en .NET 3.5 winform. El código funciona bien para ie6 o ie8, siempre que ie8 solo tenga una pestaña abierta. El problema es que si el usuario abre una nueva pestaña (pestaña 2,3, etc.) y navega a un sitio web (formulario web interno en la organización) se ejecutará el código siguiente, pero el objeto de automatización COM devolverá el HTMLDocument para la primera pestaña (pestaña 1) a pesar de que la pestaña 2 es la pestaña activa. No puedo encontrar referencias de pestañas de IE en las clases InternetExplorer o HTMLDocument en cualquier lugar. De hecho, hay muy poca documentación relacionada con pestañas de IE en los documentos de automatización IE COM.Pestaña activa ignorada por el objeto COM de InternetExplorer para 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(); 
    } 

Respuesta

4

Resulta que cada pestaña en IE 8 tiene su propio proceso y manejo. En el código original, siempre obtenía el identificador del primer IEFrame. Modifiqué el código (abajo) y ahora funciona. El cambio es que en lugar de buscar solo el primer identificador de IEFrame, el código también busca un LocationURL que coincida con la url que desencadenó el método que llama a 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 no tiene ningún API pestaña públicas (más allá de lo que le permite orientar una navegación a una nueva pestaña en primer plano o de fondo). Cada control ActiveX o BHO se carga individualmente en una instancia de pestaña individual. Intentar bajar de la colección de ShellWindows no es probable que funcione en general, en su lugar debe hacer que su complemento llegue a su sitio de alojamiento (por ejemplo, IObjectWithSite :: SetSite transmitirá esta información) lo que le permitirá determinar su pestaña de alojamiento.

Cuestiones relacionadas