Технология COM-соединения (Component Object Model) и OLE-автоматизации в среде 1С:Предприятия традиционно считается одним из наиболее уязвимых мест администрирования. При обновлении платформы, установке нескольких версий 1С на одном сервере или попытке связать базы разной разрядности (32-разрядные клиенты и 64-разрядные серверы) системные администраторы и разработчики неизбежно сталкиваются с ошибками. Самые частые среди них: "Недопустимая строка с указанием класса" (ошибка -2147221005 / 0x800401F3), "Несоответствие версий клиента и сервера 1С:Предприятия" и "Интерфейс не поддерживается" (ошибка -2147467262 / 0x80004002). Для минимизации таких проблем при техническом обслуживании систем можно автоматизировать обновление и тестирование нескольких баз 1С в фоновом режиме.
В этой статье мы подробно разберем внутренние механизмы возникновения этих конфликтов и по шагам настроим систему для их устранения. Мы рассмотрим стандартную регистрацию библиотек, создание изолированных оберток в службе компонентов Windows (COM+), научимся параллельно использовать разные версии платформы 1С через псевдонимы (алиасы) ProgID, а также программно переключать версии OLE-соединения «на лету».
Начнем с глубокого анализа причин происходящего.
---
Чтобы понять, почему простая перерегистрация библиотеки comcntr.dll не всегда решает проблему, проанализируем поведение операционной системы Windows при вызове COM-объекта 1С.
1. Конфликт версий в рамках одного процесса (проблема core83.dll).
Когда мы инициируем внутрипроцессное (Inproc) COM-соединение, библиотека comcntr.dll загружается непосредственно в адресное пространство вызывающего процесса. Это может быть процесс тонкого или толстого клиента 1cv8.exe или рабочий процесс сервера 1С rphost.exe. Вместе с этой библиотекой операционная система подтягивает базовые исполняемые модули платформы, главным из которых является core83.dll.
Если вызывающий процесс (например, сервер 1С версии 8.3.10) уже инициализировал свою версию core83.dll в памяти, а мы пытаемся через COM-соединение подключиться к базе на платформе версии 8.3.14, операционная система не будет загружать вторую версию ядра core83.dll. Она повторно использует уже находящуюся в оперативной памяти библиотеку. Новая comcntr.dll обратится к ядру старой версии и произойдет критический конфликт несовместимости, который система интерпретирует как ошибку несоответствия версий клиента и сервера.
2. Конфликт разрядности (x86 против x64).
32-разрядный процесс не может напрямую загрузить в себя 64-разрядную библиотеку comcntr.dll, и наоборот. В операционной системе Windows за поиск COM-классов для 32-разрядных клиентов на 64-битной системе отвечает специальная изолированная ветка реестра HKEY_CLASSES_ROOT\Wow6432Node\CLSID. Если регистрация проведена некорректно, 32-битный клиент (например, внешняя обработка или старая конфигурация) просто не найдет нужный класс, выдав ошибку "Недопустимая строка с указанием класса".
3. Разница между V83.COMConnector и V83.Application.
Крайне важно разделять два этих объекта автоматизации:
V83.COMConnector (CLSID {2B0C1632-A199-4350-AA2D-2AEE3D2D573A}) — это легковесный компонент. Он загружается внутри процесса, не создает оконного интерфейса, работает максимально быстро и расходует меньше ресурсов.V83.Application (CLSID {E92B75E3-2EA1-4FEC-B493-CEF3EC59FCA6}) — это полноценное OLE-приложение. При его вызове операционная система запускает полноценный сторонний процесс 1cv8.exe, инициализируя графическую оболочку (пусть даже в скрытом режиме). Он требует наличия свободной клиентской лицензии и работает существенно медленнее.---
Рассмотрим первый, самый простой шаг, который необходимо выполнить при возникновении ошибки "Недопустимая строка с указанием класса". Нам нужно зарегистрировать библиотеку comcntr.dll в операционной системе. Для этого мы должны использовать утилиту regsvr32, запущенную строго с правами администратора.
Важно помнить о разрядности операционной системы и регистрируемой библиотеки:
C:\Program Files\1cv8\...), нам следует использовать утилиту regsvr32 из папки System32:
C:\Windows\System32\regsvr32 "C:\Program Files\1cv8\8.3.16.1063\bin\comcntr.dll"
C:\Program Files (x86)\1cv8\...), то запуск утилиты необходимо производить из системной папки SysWOW64, которая отвечает за эмуляцию 32-битной среды в 64-битной Windows:
C:\Windows\SysWOW64\regsvr32 "C:\Program Files (x86)\1cv8\8.3.16.1063\bin\comcntr.dll"
Если система выдает сообщение об успешном выполнении DllRegisterServer, но при подключении ошибка сохраняется, значит, мы столкнулись с блокировкой контекста процессов. Перейдем к более надежному решению — изоляции процессов в службе COM+.
---
Чтобы обойти проблему несовместимости версий ядер 1С в одном адресном пространстве, настроим запуск comcntr.dll в изолированном системном процессе-контейнере dllhost.exe (в так называемой "обертке" COM+). Это позволит выполнять вызовы независимо от платформы, под которой работает основной процесс сервера 1С.
Выполним настройку по шагам:
dcomcnfg и нажмем Enter. Откроется оснастка "Службы компонентов".1C_COM_Connector. В области "Способ активации" обязательно установим переключатель в положение Серверное приложение. Нажмем "Далее".Агент сервера 1С:Предприятия (обычно это локальный пользователь .\USR1CV8 или доменная сервисная учетная запись), укажем ее пароль и подтвердим его. Нажмем "Далее" и завершим создание приложения.1C_COM_Connector, перейдем к ветке Компоненты.comcntr.dll нужной нам версии платформы (например, C:\Program Files\1cv8\8.3.16.1063\bin\comcntr.dll). Нажмем "Далее" и завершим установку.Теперь настроим параметры безопасности созданного контейнера. Откроем свойства нашего созданного приложения 1C_COM_Connector:
USR1CV8). Это гарантирует, что у вызывающего процесса будут полные права на чтение реестра и запуск контейнера.Для применения изменений рекомендуется принудительно перезапустить службу сервера 1С через консоль services.msc.
---
Рассмотрим ситуацию, когда на одном физическом сервере сосуществуют две разные конфигурации 1С, работающие на существенно отличающихся версиях платформы (например, старая конфигурация на 8.3.10.2466 и новая на 8.3.14.1779). Если мы зарегистрируем comcntr.dll от версии 8.3.14.1779 стандартным образом, то при попытке подключиться к старой базе по COM-соединению мы гарантированно получим ошибку несовместимости версий.
Для решения этой проблемы мы можем создать уникальные независимые псевдонимы компонентов в службе COM+. Это позволит вызывать в коде 1С именно ту версию коннектора, которая необходима для целевой базы.
Выполним эту настройку:
dcomcnfg) создадим новое пустое серверное приложение COM+ и назовем его 1C_COM_Bridges.comcntr.dll из каталога версии платформы 8.3.10.2466. По умолчанию она зарегистрируется в системе с системным ProgID V83.COMConnector.1.V83.COMConnector, откроем вкладку Взаимодействие (или "Алиасы" в зависимости от версии Windows) и зададим уникальный псевдоним компонента, например, V8.3.10.2466.COMConnector.1C_COM_Bridge_8.3.14) библиотеку comcntr.dll из каталога версии платформы 8.3.14.1779.V8.3.14.1779.COMConnector.После создания псевдонимов нам нужно проверить корректность записей в системном реестре Windows. Откроем редактор реестра regedit и выполним поиск по GUID (CLSID) созданных нами компонентов. В параметрах ветки InprocServer32 для каждого уникального CLSID должны быть прописаны точные пути к файлам comcntr.dll соответствующих версий платформы 1С.
Теперь в программном коде 1С мы можем осуществлять подключение к разным базам абсолютно безболезненно, не прибегая к постоянной перерегистрации библиотек:
// Пример подключения к базе на старой платформе 8.3.10
Попытка
КомпонентСтарый = Новый COMОбъект("V8.3.10.2466.COMConnector");
СоединениеСтарое = КомпонентСтарый.Connect("Srvr=""MyServer"";Ref=""OldBase"";Usr=""Admin"";Pwd=""123"";");
Сообщить("Успешное подключение к старой базе!");
Исключение
Сообщить("Ошибка вызова старого коннектора: " + ОписаниеОшибки());
КонецПопытки;
// Пример подключения к базе на новой платформе 8.3.14
Попытка
КомпонентНовый = Новый COMОбъект("V8.3.14.1779.COMConnector");
СоединениеНовое = КомпонентНовый.Connect("Srvr=""MyServer:1640"";Ref=""NewBase"";Usr=""Admin"";Pwd=""123"";");
Сообщить("Успешное подключение к новой базе!");
Исключение
Сообщить("Ошибка вызова нового коннектора: " + ОписаниеОшибки());
КонецПопытки;
---
Рассмотрим ситуацию, когда нам необходимо использовать не легковесный COMConnector, а полноценное OLE-соединение через V83.Application (например, для интерактивного открытия окон другой информационной базы или выполнения специфического сценария автоматизации). Как мы выяснили ранее, версия запускаемого OLE-клиента определяется системной записью в реестре.
Если у текущего пользователя операционной системы есть права администратора (или права на редактирование соответствующих разделов реестра), мы можем реализовать алгоритм автоматического переключения зарегистрированной версии 1С непосредственно перед выполнением подключения.
Проанализируем структуру реестра Windows. Версия запускаемого OLE-приложения определяется параметром по умолчанию в ветке:
HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{E92B75E3-2EA1-4FEC-B493-CEF3EC59FCA6}\LocalServer32 (для 32-разрядных процессов) или
HKEY_CLASSES_ROOT\CLSID\{E92B75E3-2EA1-4FEC-B493-CEF3EC59FCA6}\LocalServer32 (для 64-разрядных процессов).
Разберем по шагам программный код на языке 1С, который с помощью объекта WScript.Shell считывает текущую версию зарегистрированного OLE-сервера, при необходимости перезаписывает ее на требуемую, а затем принудительно завершает зависшие процессы dllhost.exe для очистки кэша операционной системы:
Процедура СменитьВерсиюOLEИУстановитьСоединение()
// Определим требуемую версию платформы для целевой базы
ТребуемаяВерсия = "8.3.14.1779";
ПутьКИсполняемомуФайлу = "C:\Program Files\1cv8\" + ТребуемаяВерсия + "\bin\1cv8.exe";
// GUID класса V83.Application
CLSID = "{E92B75E3-2EA1-4FEC-B493-CEF3EC59FCA6}";
КлючРеестра = "HKEY_CLASSES_ROOT\CLSID\" + CLSID + "\LocalServer32\";
Попытка
WshShell = Новый COMОбъект("WScript.Shell");
// Считаем текущее значение из реестра
ТекущееЗначение = WshShell.RegRead(КлючРеестра);
Если Найти(ТекущееЗначение, ТребуемаяВерсия) = 0 Тогда
// Версии не совпадают, требуется перезапись значения реестра
Сообщить("Регистрируем версию " + ТребуемаяВерсия + " для OLE-соединения...", СтатусСообщения.Информация);
// Записываем путь к исполняемому файлу нужной версии платформы
WshShell.RegWrite(КлючРеестра, ПутьКИсполняемомуФайлу);
// Принудительно завершаем процессы dllhost.exe для сброса кэша COM
ЗапуститьПриложение("taskkill.exe /f /im dllhost.exe",, Истина);
Сообщить("Регистрация успешно обновлена.", СтатусСообщения.Информация);
КонецЕсли;
Исключение
ВызватьИсключение "Не удалось изменить версию OLE-сервера в реестре. "
+ "Убедитесь, что у пользователя достаточно прав (запуск от имени Администратора). "
+ "Описание ошибки: " + ОписаниеОшибки();
КонецПопытки;
// Теперь выполняем стандартное OLE-подключение
Попытка
OLEПодключение = Новый COMОбъект("V83.Application");
ПараметрыПодключения = "Srvr=""MyServer"";Ref=""Base14"";Usr=""Admin"";Pwd=""123"";";
РезультатПодключения = OLEПодключение.Connect(ПараметрыПодключения);
Если РезультатПодключения Тогда
Сообщить("Успешно подключено через OLE-соединение новой версии!");
// Выполняем полезную работу
// ...
Иначе
Сообщить("Не удалось установить OLE-соединение.");
КонецЕсли;
Исключение
Сообщить("Критическая ошибка OLE-подключения: " + ОписаниеОшибки(), СтатусСообщения.Важное);
КонецПопытки;
КонецПроцедуры
Этот метод эффективно решает проблему динамического переключения платформ для OLE-соединений на рабочих станциях пользователей и серверах терминалов, где выполняются регламентные или ручные выгрузки данных. Для исключения человеческого фактора можно внедрить роботизацию повторяющихся операций в 1С через визуальный конструктор сценариев.
---
Важно признать, что технологии COM и OLE официально признаны устаревшими. Сама корпорация Microsoft постепенно сокращает их поддержку в современных версиях операционных систем Windows (особенно на архитектуре ARM), отдавая предпочтение кроссплатформенным веб-технологиям. Разработчики платформы 1С также настоятельно рекомендуют отказываться от COM-соединений в пользу веб-сервисов (SOAP) и HTTP-сервисов (REST).
Однако создание веб-сервиса требует написания программного кода как на стороне источника, так и на стороне приемника. Если перед нами стоит задача быстро настроить обмен данными без программирования сложных интеграционных шин, идеальной альтернативой COM-соединению выступает встроенный интерфейс OData (REST API 1С).
Интерфейс OData позволяет получать доступ к любым объектам метаданных 1С (справочникам, документам, регистрам) посредством стандартных HTTP-запросов напрямую, возвращая и принимая данные в легком формате JSON или XML.
Рассмотрим, как опубликовать и использовать этот интерфейс:
MyBaseOData) и каталог на диске.Теперь мы можем обращаться к базе данных 1С с помощью стандартных HTTP-запросов из любой внешней системы, включая другие конфигурации 1С. Для отправки запроса и получения данных используется стандартный объект 1С HTTPСоединение. Посмотрим на практический пример получения списка номенклатуры по OData из другой базы:
Процедура ПолучитьДанныеПоOData()
// Параметры веб-сервера и базы
Сервер = "192.168.1.100";
ИмяПубликации = "MyBaseOData";
// Формируем запрос к стандартному интерфейсу OData для справочника Номенклатура
// Запросим первые 10 элементов
Ресурс = "/" + ИмяПубликации + "/odata/standard.odata/Catalog_Номенклатура?$top=10&$format=json";
// Настроим авторизацию (пользователь базы 1С)
Логин = "ODataUser";
Пароль = "SecretPassword";
HTTPСоединение = Новый HTTPСоединение(Сервер,,,,,, Новый ЗащищенноеСоединениеOpenSSL());
HTTPЗапрос = Новый HTTPЗапрос(Ресурс);
// Кодируем учетные данные в формат Base64 для Basic-авторизации
ИмяИПароль = Логин + ":" + Пароль;
ЗашифрованныеДанные = Base64Строка(ПолучитьДвоичныеДанныеИзСтроки(ИмяИПароль, КодировкаТекста.UTF8));
ЗашифрованныеДанные = СтрЗаменить(ЗашифрованныеДанные, Символы.ПС, "");
HTTPЗапрос.Заголовки.Вставить("Authorization", "Basic " + ЗашифрованныеДанные);
Попытка
HTTPОтвет = HTTPСоединение.Получить(HTTPЗапрос);
Если HTTPОтвет.КодСостояния = 200 Тогда
СтрокаJSON = HTTPОтвет.ПолучитьТелоКакСтроку();
// Распакуем JSON во временную таблицу или структуру
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(СтрокаJSON);
Результат = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
// Обработаем полученные элементы
МассивЭлементов = Результат.value;
Для Каждого Элемент Из МассивЭлементов Цикл
Сообщить("Код: " + Элемент.Code + " | Наименование: " + Элемент.Description);
КонецЦикла;
Иначе
Сообщить("Ошибка запроса. Код состояния HTTP: " + HTTPОтвет.КодСостояния);
КонецЕсли;
Исключение
Сообщить("Не удалось установить HTTP-соединение: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Переход на OData полностью избавляет нас от необходимости регистрировать библиотеки, бороться с правами доступа к реестру Windows, настраивать COM+ и решать конфликты разрядности. Это современный, безопасный и максимально стабильный способ интеграции систем на платформе 1С:Предприятие. С его помощью можно организовать автоматический обмен данными между базами 1С по расписанию, используя веб-сервисы вместо COM-соединений.