При интеграции «1С:Предприятия» с внешними информационными системами разработчики часто сталкиваются с использованием технологии COM. Одной из классических проблем является интеграция с системой ЭТРАН ОАО «РЖД» с использованием специализированной библиотеки EtranASUGO.EtranASUGO. Сценарий, при котором код отлично работает в интерактивном режиме на рабочем компьютере пользователя, но завершается аварийно при запуске в регламентном задании на сервере, является стандартным. Выясним, почему возникает ошибка «-2147221005(0x800401F3): Недопустимая строка с указанием класса», и детально рассмотрим все способы её решения.
Для начала проанализируем разницу в контекстах выполнения. Когда мы запускаем внешнюю обработку или код в обычной форме интерактивно, он выполняется в контексте &НаКлиенте на локальном компьютере пользователя. В этот момент операционная система Windows обращается к локальному реестру, находит зарегистрированный класс EtranASUGO.EtranASUGO и успешно инициализирует COM-объект.
При запуске регламентного задания выполнение происходит строго в контексте &НаСервере. Служба «1С:Предприятия» (процесс rphost.exe) пытается выполнить ту же самую строку кода:
Etran = Новый COMОбъект("EtranASUGO.EtranASUGO");
Однако на самом сервере 1С эта COM-компонента не установлена и не зарегистрирована. Операционная система сервера ничего не знает о данном классе, в результате чего платформа генерирует ошибку инициализации конструктора.
Многие разработчики совершают ошибку, полагая, что если на сервере запущено другое регламентное задание с использованием COM-технологий (например, работающее с Excel или ADODB), то среда COM настроена полностью. Это не так: поддержка COM-технологии в целом включена на сервере по умолчанию, но каждую конкретную стороннюю библиотеку необходимо регистрировать на сервере индивидуально.
Рассмотрим по шагам три основных метода решения этой проблемы: от локальной настройки сервера до современного перехода на HTTP-протокол.
Если архитектура вашей сети позволяет установить клиентскую часть ЭТРАН и средство защиты ViPNet непосредственно на сервер 1С, это будет самым простым решением. Однако здесь нас подстерегает критическая проблема — разница разрядностей процессов.
Сервер «1С:Предприятия» в подавляющем большинстве случаев является 64-разрядным (x64). В то же время библиотека EtranASUGO.dll является устаревшей 32-разрядной (x86) компонентой. Процесс rphost.exe (x64) физически не способен напрямую загрузить в свое адресное пространство 32-битный dll-файл. Обычная регистрация через утилиту regsvr32 не решит проблему в серверном контексте 1С.
Чтобы обойти это ограничение, мы настроим суррогатный процесс COM+ в Windows, который выступит мостом между 64-битной 1С и 32-битной компонентой.
Выполним настройку по шагам:
EtranASUGO.dll на сервер 1С (лучше положить его в системную папку, например, C:\Windows\SysWOW64\ для 32-битных библиотек).
C:\Windows\SysWOW64\regsvr32.exe C:\Windows\SysWOW64\EtranASUGO.dll
Win + R, введите dcomcnfg.exe и нажмите Enter.Etran_x86_Wrapper. В разделе «Способ активации» обязательно укажите Серверное приложение (Server application) и нажмите «Далее».USR1CV8), либо выберите системную учетную запись (Interactive User / Network Service), в зависимости от настроек безопасности вашей сети. Нажмите «Готово».Etran_x86_Wrapper, найдите в нем ветку Компоненты. Нажмите на нее правой кнопкой мыши и выберите Создать -> Компонент.EtranASUGO.EtranASUGO (обязательно установите флаг «32-разрядные компоненты», если он доступен). Завершите импорт.После выполнения этих действий операционная система Windows при попытке создания объекта EtranASUGO.EtranASUGO из 64-битного процесса 1С автоматически запустит системный изолированный процесс-суррогат dllhost.exe (x86), который загрузит библиотеку и организует маршалинг данных. Проблема разрядности будет решена.
В некоторых случаях установить компоненту непосредственно на сервер 1С невозможно. Например, если для работы компоненты требуется активное защищенное соединение через ПО «ViPNet Client», а оно настроено только на одном конкретном сервере базы данных (например, под управлением ОС Windows с сетевым именем trnh-db-02).
Платформа 1С позволяет инициализировать COM-объект удаленно, передав имя компьютера вторым параметром конструктора:
Etran = Новый COMОбъект("EtranASUGO.EtranASUGO", "trnh-db-02");
Однако при попытке выполнить этот код вы можете столкнуться с ошибкой: «Сервер RPC недоступен (0x800706BA)». Проанализируем причины этой ошибки и настроим DCOM:
135 (RPC Endpoint Mapper), а также динамический пул портов (в современных ОС Windows это диапазон 49152–65535). Если брандмауэр на сервере 1С или на сервере trnh-db-02 блокирует эти порты, удаленное подключение не состоится. Для тестирования временно отключите брандмауэр на обеих машинах. Для постоянной работы добавьте правила, разрешающие трафик по порту 135 и всему диапазону динамических портов RPC для соответствующих IP-адресов.USR1CV8. При попытке удаленного вызова сервер trnh-db-02 отклонит запрос, так как он не знает этого пользователя, либо у него нет прав.
DOMAIN\Service1C).trnh-db-02 в утилите dcomcnfg откройте свойства компьютера, перейдите на вкладку «Безопасность COM» и добавьте пользователя DOMAIN\Service1C в разделы «Разрешения на запуск и активацию» и «Разрешения на доступ», выдав ему полные права.trnh-db-02 (на вкладке «Удостоверение») жестко укажите конкретного доменного или локального пользователя, под которым предварительно выполнен вход в систему и успешно настроена работа ViPNet.Использование COM-технологий для межсерверного взаимодействия считается устаревшим и нестабильным решением. Сама библиотека EtranASUGO под капотом является лишь оберткой, которая формирует XML-пакеты, оборачивает их в SOAP-конверты и отправляет HTTP-запросы на веб-сервер РЖД.
Мы можем полностью отказаться от использования нестабильной COM-компоненты на сервере 1С и выполнять веб-запросы напрямую средствами платформы 1С. Это избавит нас от проблем с регистрацией библиотек, разрядностью процессов и настройкой DCOM.
Проанализируем пример кода для прямой отправки SOAP-запроса в систему ЭТРАН через HTTPСоединение:
// Сформируем тело XML-запроса по спецификации ЭТРАН
ТекстXML =
"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:etr=""http://www.rzd.ru/etran"">
| <soapenv:Header/>
| <soapenv:Body>
| <etr:GetDislocation>
| <etr:xmlRequest><![CDATA[<RequestDocument>...данные запроса...</RequestDocument>]]></etr:xmlRequest>
| </etr:GetDislocation>
| </soapenv:Body>
|</soapenv:Envelope>";
// Настроим параметры подключения к серверу ЭТРАН
СерверАдрес = "10.x.x.x"; // IP-адрес сервера ЭТРАН в сети ViPNet
Порт = 80; // Стандартный порт HTTP-сервиса ЭТРАН
// Создаем HTTP-соединение. Если ViPNet установлен на другом сервере-прокси,
// мы можем передать параметры прокси-сервера прямо в конструктор
Прокси = Новый ИнтернетПрокси;
// Прокси.Установить("http", "trnh-db-02", 3128); // Пример использования прокси-сервера
HTTPСоединение = Новый HTTPСоединение(СерверАдрес, Порт, , , Прокси);
HTTPЗапрос = Новый HTTPЗапрос("/EtranHttpSrvr.dll/soap");
HTTPЗапрос.Заголовки.Вставить("Content-Type", "text/xml; charset=utf-8");
HTTPЗапрос.Заголовки.Вставить("SOAPAction", "http://www.rzd.ru/etran/GetDislocation"); // Метод SOAP
HTTPЗапрос.УстановитьТелоИзСтроки(ТекстXML, КодировкаТекста.UTF8, ИспользованиеМаркераВремени.НеИспользовать);
Попытка
HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
Если HTTPОтвет.КодСостояния = 200 Тогда
РезультатТекст = HTTPОтвет.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
// Выполняем парсинг полученного XML-ответа средствами 1С (ЧтениеXML)
Иначе
ЗаписьЖурналаРегистрации("ИнтеграцияЭТРАН", УровеньЖурналаРегистрации.Ошибка, , ,
"Ошибка сервера: " + HTTPОтвет.КодСостояния);
КонецЕсли;
Исключение
ЗаписьЖурналаРегистрации("ИнтеграцияЭТРАН", УровеньЖурналаРегистрации.Ошибка, , ,
"Ошибка сетевого соединения: " + ОписаниеОшибки());
КонецПопытки;
Если защищенный канал ViPNet развернут исключительно на выделенном сервере (например, trnh-db-02), а сервер 1С находится в общей локальной сети, мы можем настроить прокси-сервер (например, Squid или CCProxy) на машине trnh-db-02. После этого сервер 1С сможет отправлять стандартные HTTP-запросы через указанный прокси-сервер, транслируя их в защищенную сеть РЖД. При этом нам не потребуются никакие COM-объекты, а стабильность работы регламентных заданий увеличится в разы.