5 votes

Onglet actif ignoré par l'objet COM d'InternetExplorer pour IE 8

Il s'agit d'un code d'authentification unique sur le web qui fonctionne sur une plateforme winform .net 3.5. Le code fonctionne bien pour ie6 ou ie8 tant que ie8 n'a qu'un seul onglet ouvert. Le problème est que si l'utilisateur ouvre un nouvel onglet (onglet 2, 3, etc.) et navigue vers un site web (formulaire web interne à l'organisation), le code ci-dessous sera exécuté mais l'objet d'automatisation COM d'ie renverra le HTMLDocument pour le premier onglet (onglet 1) même si l'onglet 2 est l'onglet actif. Je ne trouve aucune référence aux onglets IE dans les classes InternetExplorer ou HTMLDocument. En fait, il y a très peu de documentation relative aux onglets IE dans les documents d'automatisation IE 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();
    }

4voto

JimSTAT Points 457

Il s'avère que chaque onglet dans IE 8 a son propre processus et sa propre poignée. Dans le code original, je récupérais toujours le handle du premier IEFrame. J'ai modifié le code (ci-dessous) et maintenant cela fonctionne. Le changement est qu'au lieu de chercher seulement le handle du premier IEFrame, le code cherche aussi un LocationURL qui correspond à l'url qui a déclenché la méthode qui appelle 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)

3voto

EricLaw Points 28850

Internet Explorer ne dispose d'aucune API d'onglet publique (hormis la possibilité de cibler une navigation vers un nouvel onglet de premier plan ou d'arrière-plan). Chaque contrôle ActiveX ou BHO est chargé individuellement dans une instance d'onglet individuelle. Essayer de descendre de la collection ShellWindows n'est pas susceptible de fonctionner en général, vous devriez plutôt faire en sorte que votre plugin communique avec son site d'hébergement (par exemple, IObjectWithSite::SetSite transmettra cette information), ce qui vous permettra de déterminer votre onglet d'hébergement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X