Question

Ceci est signe unique web sur le code qui fonctionne sur un NET 3.5 WinForm. Le code fonctionne bien pour IE6 ou IE8 aussi longtemps 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 accède à un site web (formulaire web interne dans l'organisation), le ci-dessous le code sera exécuté mais le-à-dire l'objet d'automatisation COM renverra le HTMLDocument pour la première languette (tab 1), même si l'intercalaire 2 est l'onglet actif. Je ne trouve aucune référence de l'onglet IE dans les classes InternetExplorer ou HTMLDocument partout. En fait, il y a très peu onglet IE anywherer de la documentation relative à l'automatisation IE COM docs.

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();
    }
Était-ce utile?

La solution

Il se trouve que chaque onglet dans Internet Explorer 8 a son propre processus et poignée. Dans le code original que je recevais toujours été la poignée de la première IEFrame. Je modifié le code (ci-dessous) et maintenant il fonctionne. Le changement est qu'au lieu de chercher seulement la première manche IEFrame, le code semble également un LocationURL qui correspond à l'URL triggerd 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)

Autres conseils

Internet Explorer n'a pas d'API d'onglet publique (au-delà de ce qui vous permet de cibler une navigation vers un nouvel onglet premier plan ou arrière-plan). Chaque contrôle ActiveX ou BHO est chargé individuellement dans une instance de chaque onglet. Essayer de marcher vers le bas de la collection ShellWindows ne risque pas de travail en général, au lieu que vous devez avoir votre plugin se tourner vers ses sites d'hébergement (par exemple IObjectWithSite :: SetSite va transmettre cette information) qui vous permettra de déterminer votre onglet d'hébergement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top