Имя: Пароль:
IT
 
Работа с несколькими экземплярами InternetExplorer.Application через COM
0 Codimca
 
05.08.14
17:07
Обнаружил, что платформа 1С некорректно работает с несколькими экземплярами Интернет-эксплорера (Windows 7, IE 11). Если в системе запущен 1 экземпляр приложения iexplore.exe (1 страница в обозревателе) - всё норм. Но стоит запустить ещё и возникают проблемы со свойством Document.
Нашёл решение в использовании объекта MSScriptControl.ScriptControl: выполнять действия с объектом InternetExplorer.Application через него.
Чтобы увидеть как это функционирует, создайте внешнюю обработку, добавьте на форму 4 широких надписи с именами НадписьСостояние0, НадписьСостояние1, НадписьСостояние2, НадписьСостояние3. Для кнопки "Выполнить" добавьте обработчик события "Нажатие":
    IE = Новый COMОбъект("InternetExplorer.Application");
    IE.Visible = Истина;
    //IE.Silent = Ложь;

    Состояние("Запуск Internet Explorer и переход на нужные сайты");
    ПроцессыЭксплорера = Новый Массив;
    IE.Navigate2("ССЫЛКА1");
    IE.Navigate2("ССЫЛКА2", 4096);
    IE.Navigate2("ССЫЛКА3", 4096);
    IE.Navigate2("ССЫЛКА4", 4096);
    
    ПодключитьОбработчикОжидания("ОбновитьСостояния",1);

Замените строки ССЫЛКА1, ССЫЛКА2, ССЫЛКА3, ССЫЛКА4 на нужные адреса веб-страниц.
Добавьте процедуру
Процедура ОбновитьСостояния()
    Оболочка = Новый COMОбъект("Shell.Application");
    Скрипт=Новый COMОбъект("MSScriptControl.ScriptControl");
    Скрипт.language="JScript";
    ИндексПроцесса = 0;
    // Получение всех открытых процессов - для каждой вкладки происходит создание нового процесса
    Для каждого ОкноПроцесса Из Оболочка.Windows() Цикл
        Если ОкноПроцесса.Name = "Internet Explorer" Тогда
            СостояниеПроцесса = "";
            СостояниеПроцесса = СостояниеПроцесса+"Адрес: " + ОкноПроцесса.LocationURL + Символы.ПС;
            СостояниеПроцесса = СостояниеПроцесса+"Busy: " + ОкноПроцесса.Busy + Символы.ПС;
            СостояниеПроцесса = СостояниеПроцесса+"ReadyState: " + ОкноПроцесса.ReadyState + Символы.ПС;
            Попытка
                СостояниеПроцесса = СостояниеПроцесса+"Document.readyState: " + ОкноПроцесса.Document.readyState + Символы.ПС;
            Исключение
                СостояниеПроцесса = СостояниеПроцесса+"Document.readyState: " + ОписаниеОшибки() + Символы.ПС;
            КонецПопытки;
            Попытка
                Скрипт.AddObject("IE",ОкноПроцесса);
                СостояниеПроцесса = СостояниеПроцесса+"Document.readyState - ч/з скрипт: " + Скрипт.Eval("IE.document.readyState") + Символы.ПС;
            Исключение
                СостояниеПроцесса = СостояниеПроцесса+"Document.readyState - ч/з скрипт: " + ОписаниеОшибки() + Символы.ПС;
            КонецПопытки;
            Скрипт.Reset();
            Попытка
                СостояниеПроцесса = СостояниеПроцесса+"Длина строки Document.documentElement.innerHTML: " + СтрДлина(ОкноПроцесса.Document.documentElement.innerHTML) + Символы.ПС;
            Исключение
                СостояниеПроцесса = СостояниеПроцесса+"Длина строки Document.documentElement.innerHTML: " + ОписаниеОшибки() + Символы.ПС;
            КонецПопытки;
            Попытка
                Скрипт.AddObject("IE",ОкноПроцесса);
                СостояниеПроцесса = СостояниеПроцесса+"Длина строки Document.documentElement.innerHTML - ч/з скрипт: " + СтрДлина(Скрипт.Eval("IE.document.documentElement.innerHTML"));
            Исключение
                СостояниеПроцесса = СостояниеПроцесса+"Длина строки Document.documentElement.innerHTML - ч/з скрипт: " + ОписаниеОшибки();
            КонецПопытки;
            Скрипт.Reset();
            //Если СостояниеПроцесса Тогда    
            //    СтраницПолучено = СтраницПолучено + 1;
            //КонецЕсли;
            Если ИндексПроцесса=0 Тогда
                ЭлементыФормы.НадписьСостояние0.Заголовок = СостояниеПроцесса;
            ИначеЕсли ИндексПроцесса=1 Тогда
                ЭлементыФормы.НадписьСостояние1.Заголовок = СостояниеПроцесса;
            ИначеЕсли ИндексПроцесса=2 Тогда
                ЭлементыФормы.НадписьСостояние2.Заголовок = СостояниеПроцесса;
            ИначеЕсли ИндексПроцесса=3 Тогда
                ЭлементыФормы.НадписьСостояние3.Заголовок = СостояниеПроцесса;
            КонецЕсли;
            ИндексПроцесса = ИндексПроцесса + 1;
        КонецЕсли;
        ОбработкаПрерыванияПользователя();
    КонецЦикла;
КонецПроцедуры
На событие "ПриЗАкрытии" добавьте код
    
    Состояние("Выгрузка объектов интернет-эксплорера");
    ПроцессыЭксплорера = Новый Массив;
    Шелл = Новый COMОбъект("Shell.Application");
    Для каждого ОкноПроцесса Из Шелл.Windows() Цикл
        Если ОкноПроцесса.Name = "Internet Explorer" Тогда
            ПроцессыЭксплорера.Добавить(ОкноПроцесса);
        КонецЕсли;
    КонецЦикла;
    Для каждого ОкноПроцесса Из ПроцессыЭксплорера Цикл
        ОкноПроцесса.Quit();
    КонецЦикла;
1 Torquader
 
06.08.14
10:20
А почему бы не создать несколько объектов InternetExplorer.Application ?
Будет работать в несколько потоков и будет создано несколько InternetExplorer и никогда ещё не подводило.
2 SUA
 
06.08.14
10:23
>>Работа с несколькими экземплярами InternetExplorer.Application
а почему в коде 1?
3 Torquader
 
07.08.14
17:28
(2) Наверное, он должен был назвать тему - "одновременное открытие нескольких страниц в одном экземпляре InternetExplorer"
4 Codimca
 
18.08.14
17:20
(3) Создание нескольких объектов InternetExplorer.Application приводило к неправильной работе свойства Document всех объектов, кроме одного (самого первого)
(2) Каждая вкладка - новый экземпляр объекта
5 Torquader
 
23.08.14
21:23
(4) Каждая вкладка - это один и тот же OLE-сервер.
Если не нравится использоваться вкладки, то можно открывать окна (window.open, window.showModelessDialog) или наваять iframe-ы в одной странице.