Как исправить ошибку создания COM-объекта MSSOAP.SoapClient30 в 1С на 64-разрядной системе?

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет IT и автоматизация бизнеса
← На главную

При интеграции 1С с внешними SOAP веб-сервисами с использованием устаревшей библиотеки MSSOAP.SoapClient30 разработчики часто сталкиваются с ошибкой инициализации COM-соединения при переносе рабочего кода на сервер. Разберем причины возникновения этой проблемы и рассмотрим подробные варианты ее устранения.

Типичный текст ошибки в журнале регистрации или окне сообщений выглядит следующим образом:


{ОбщийМодуль.МодульРегламентныхЗаданий.Модуль(277)}: Ошибка при вызове конструктора (COMОбъект)
    Клиент = Новый COMОбъект("MSSOAP.SoapClient30");
по причине:
-2146959355(0x80080005): Ошибка при выполнении приложения-сервера

Причины возникновения ошибки 0x80080005

Проанализируем архитектурные особенности работы COM-компонентов в среде Windows Server и платформы 1С:

  1. Несовместимость разрядности процессов (x86 vs x64): Библиотеки MSSOAP30.dll и msscript.ocx (компонент MSScriptControl.ScriptControl) существуют исключительно в 32-разрядном исполнении. 64-битный рабочий процесс сервера 1С:Предприятия (rphost.exe) не может загрузить 32-битные DLL напрямую в собственное адресное пространство.
  2. Контекст регламентных и фоновых заданий: Регламентные задания выполняются на стороне сервера приложений в неинтерактивной сессии (Session 0). При попытке запуска COM-объекта под учетной записью службы (например, USR1CV8) без предварительно настроенного суррогатного процесса dllhost.exe операционная система возвращает ошибку 0x80080005 (CO_E_SERVER_EXEC_FAILURE).
  3. Отсутствие прав DCOM: Служба сервера 1С не имеет прав на локальную активацию и запуск соответствующего компонента в оснастке службы компонентов.

Способ 1. Настройка 32-битного суррогата в Службах компонентов COM+

Разберем по шагам, как заставить 32-разрядный COM-компонент корректно работать в 64-битной операционной системе и сервере 1С:

  1. Установка пакета: Установим дистрибутив Microsoft SOAP Toolkit 3.0 на сервер, где физически выполняется вызов кода (терминальный сервер или сервер 1С:Предприятия).
  2. Создание приложения COM+:
    1. Откроем оснастку Службы компонентов (выполним команду dcomcnfg в командной строке).
    2. Перейдем в ветку Компьютеры > Мой компьютер > Приложения COM+.
    3. Нажмем правой кнопкой мыши по папке Приложения COM+ и выберем Создать > Приложение.
    4. В мастере выберем Создать новое приложение, зададим понятное имя (например, SoapClient30_x86) и укажем тип активации Серверное приложение (Server Application).
    5. На шаге выбора учетной записи выберем Указанный пользователь и введем учетные данные пользователя с правами локального администратора или данные служебного пользователя, под которым запускается агент сервера 1С (USR1CV8).
  3. Добавление компонентов в приложение:
    1. В созданной ветке приложения перейдем в папку Компоненты.
    2. Нажмем правой кнопкой мыши > Создать > Компонент.
    3. Выберем пункт Установка новых компонентов и укажем путь к файлу библиотеки: C:\Program Files (x86)\Common Files\MSSoap\Binaries\MSSOAP30.dll.
    4. Аналогичным образом при необходимости добавим компонент msscript.ocx из папки C:\Windows\SysWOW64\, если в программном коде используется MSScriptControl.ScriptControl.
  4. Принудительный запуск в 32-разрядном пуле:
    1. Откроем свойства созданного приложения COM+.
    2. На вкладке Дополнительно (Advanced) проверим, что включен запуск 32-разрядного пула процессов (32-bit surrogate).
    3. На вкладке Безопасность убедимся, что учетная запись службы 1С включена в список пользователей с правами запуска и доступа.
  5. Перезапуск служб: Выполним перезапуск сервера 1С или перезагрузим операционную систему для применения всех изменений.

Посмотрим на типовой пример кода 1С, который работает с данным COM-объектом после правильной настройки суррогата:


Клиент = Новый COMОбъект("MSSOAP.SoapClient30");    
Если ПустаяСтрока(ПространствоИмен) Тогда
    Клиент.MSSoapInit(АдресWSDL, ИмяСервиса, ИмяПорта);
Иначе
    Клиент.MSSoapInit2(АдресWSDL, "", ИмяСервиса, ИмяПорта, ПространствоИмен);
КонецЕсли;

// Установка параметров соединения через оболочку VBScript
Оболочка = Новый COMОбъект("MSScriptControl.ScriptControl");
Оболочка.Language = "vbscript";
Оболочка.AddCode("
    |Sub SETConnectorProperty(Client, PropertyName, PropertyValue)
    |    Client.ConnectorProperty(PropertyName) = PropertyValue
    |End Sub
    |Sub SETClientProperty(Client, PropertyName, PropertyValue)
    |    Client.ClientProperty(PropertyName) = PropertyValue
    |End Sub
|");

Оболочка.Run("SETConnectorProperty", Клиент, "Timeout", 30000);

Способ 2. Отказ от устаревшего COM в пользу нативного HTTPСоединения (Рекомендуемый)

Использование MSSOAP.SoapClient30 и MSScriptControl несет архитектурные риски: библиотеки сняты с поддержки производителем, создают нестабильность при вызове через dllhost.exe и не работают на Linux-серверах 1С. Встроенные средства платформы 1С позволяют выполнять любые SOAP-запросы напрямую через протокол HTTP.

Разберем, как реализовать прямой SOAP-запрос с помощью объектов HTTPСоединение и HTTPЗапрос:


// Формируем тело SOAP-конверта (Envelope)
ТелоЗапросаXML = 
"<?xml version=""1.0"" encoding=""utf-8""?>
|<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" 
|               xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" 
|               xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
|  <soap:Body>
|    <GetItemsList xmlns=""http://tempuri.org/"">
|      <ItemCode>12345</ItemCode>
|    </GetItemsList>
|  </soap:Body>
|</soap:Envelope>";

// Настраиваем соединение с сервером
Сервер = "api.service.ru";
Порт = 443;
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение(Сервер, Порт, , , , 30, ЗащищенноеСоединение);

// Подготавливаем заголовки запроса
Заголовки = Новый Соответствие();
Заголовки.Вставить("Content-Type", "text/xml; charset=utf-8");
Заголовки.Вставить("SOAPAction", "http://tempuri.org/GetItemsList");

// Создаем и отправляем HTTP-запрос
Запрос = Новый HTTPЗапрос("/soap/service.asmx", Заголовки);
Запрос.УстановитьТелоИзСтроки(ТелоЗапросаXML, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

Ответ = Соединение.ОтправитьДляОбработки(Запрос);

Если Ответ.КодСостояния = 200 Тогда
    СтрокаОтветаXML = Ответ.ПолучитьТелоКакСтроку();
    // Обрабатываем полученный XML с помощью ЧтениеXML или ПостроительDOM
    Чтение = Новый ЧтениеXML();
    Чтение.УстановитьСтроку(СтрокаОтветаXML);
    Построитель = Новый ПостроительDOM();
    ДокументDOM = Построитель.Прочитать(Чтение);
    // Извлекаем полезные данные из DOM-модели
Иначе
    ВызватьИсключение "Ошибка выполнения SOAP-запроса: " + Ответ.КодСостояния;
КонецЕсли;

Переход на нативные механизмы платформы 1С (HTTPСоединение, ЗаписьXML, ПостроительDOM) полностью исключает зависимость от операционной системы, разрядности сервера и настроек COM+.

← На главную