Активная вкладка игнорируется COM-объектом InternetExplorer для IE 8 - PullRequest
5 голосов
/ 07 сентября 2011

Это веб-код единого входа, который запускается на win-форме .net 3.5. Код работает нормально для ie6 или ie8 до тех пор, пока ie8 имеет только одну открытую вкладку. Проблема в том, что если пользователь откроет новую вкладку (вкладка 2,3 и т. Д.) И перейдет на веб-сайт (веб-форма, внутренняя в организации), будет выполнен приведенный ниже код, но объект автоматизации COM, то есть вернет HTMLDocument для первой вкладки (вкладка 1), хотя вкладка 2 является активной вкладкой. Я не могу найти ссылки на вкладки IE в классах InternetExplorer или HTMLDocument. На самом деле, в документации по автоматизации COM COM очень мало документации, связанной с вкладками IE.

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

Ответы [ 2 ]

4 голосов
/ 08 сентября 2011

Оказывается, что каждая вкладка в IE 8 имеет свой собственный процесс и дескриптор. В исходном коде я всегда получал дескриптор от первого IEFrame. Я изменил код (ниже), и теперь он работает. Изменение состоит в том, что вместо того, чтобы искать только первый дескриптор IEFrame, код также ищет LocationURL, который совпадает с URL, который вызвал метод, вызывающий 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 голосов
/ 08 сентября 2011

Internet Explorer не имеет API-интерфейсов общедоступных вкладок (кроме того, что позволяет вам ориентировать навигацию на новый передний план или фоновую вкладку).Каждый элемент управления ActiveX или BHO загружается индивидуально в отдельный экземпляр вкладки.Попытка отойти от коллекции ShellWindows, скорее всего, не сработает, вместо этого вам нужно, чтобы ваш плагин обращался к своему хостинговому сайту (например, IObjectWithSite :: SetSite будет передавать эту информацию), что позволит вам определить вкладку хостинга.

...