Почему возникает ошибка «Класс не зарегистрирован» при создании COM-объекта в обычной форме 1С и как её исправить?

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

При интеграции 1С со сторонними библиотеками через технологию COM разработчики нередко сталкиваются с ситуацией, когда один и тот же код успешно выполняется в управляемой форме на сервере, но вызывает исключение «Ошибка при вызове конструктора (COMОбъект): Класс не зарегистрирован» при выполнении в модуле обычной формы. Разберем детально, почему это происходит и какими способами можно устранить проблему.

Рассмотрим типовой сценарий, в котором воспроизводится ошибка. В управляемой форме код выполняется с директивой &НаСервере:


&НаКлиенте
Процедура Подписать(Команда)
    ПодписатьНаСервере();
КонецПроцедуры

&НаСервере
Процедура ПодписатьНаСервере()
    Попытка
        PDF = Новый COMОбъект("DebenuPDFLibrary64AX1113.PDFLibrary");
    Исключение
        Сообщить("Не зарегистрирована библиотека!");
        Сообщить(ОписаниеОшибки());
        Возврат;
    КонецПопытки;    
КонецПроцедуры

При попытке перенести этот же вызов в модуль обычной формы возникает ошибка:


Процедура Подписать()
    Попытка
        PDF = Новый COMОбъект("DebenuPDFLibrary64AX1113.PDFLibrary");
    Исключение
        Сообщить("Не зарегистрирована библиотека!");
        Сообщить(ОписаниеОшибки());
        Возврат;
    КонецПопытки;    
КонецПроцедуры

Анализ причин: разрядность процессов и контекст выполнения

Выясним причину такого поведения платформы. Основной фактор здесь — несовпадение разрядности клиентского приложения 1С и регистрируемой COM-библиотеки.

  1. Разрядность клиента и сервера: Серверная служба 1С (процесс rphost.exe) чаще всего развернута в 64-разрядном варианте (x64). При выполнении серверной процедуры управляемой формы 64-битный процесс сервера 1С без проблем загружает 64-битную COM-библиотеку.
  2. Контекст обычной формы: В обычных формах весь код модуля формы выполняется исключительно в контексте толстого клиента на рабочей станции пользователя. В платформах 1С 8.2 клиентские приложения выпускались только в 32-разрядном варианте (x86). Директивы компиляции &НаСервере и &НаКлиенте в обычных формах недоступны.
  3. Ограничения архитектуры Windows: 32-битный исполняемый процесс не может напрямую загрузить в свое адресное пространство 64-битную внутрипроцессную динамическую библиотеку (InprocServer32 DLL). При обращении к реестру 32-битный процесс ищет ProgID и CLSID в ветке WOW6432Node, где 64-битная библиотека не зарегистрирована. В результате платформа 1С возвращает системную ошибку о том, что класс не зарегистрирован.

Рассмотрим практические варианты решения этой задачи в зависимости от архитектуры вашей системы.

Вариант 1: Использование библиотеки соответствующей разрядности (32-bit)

Если логика должна гарантированно выполняться на стороне клиента, самым простым и надежным решением является установка и регистрация 32-разрядной версии COM-компоненты.

  1. Найдем или запросим у поставщика 32-битную версию DLL (например, DebenuPDFLibraryAX1113.dll вместо версии с суффиксом 64).
  2. Зарегистрируем библиотеку в 64-разрядной операционной системе Windows через 32-битный regsvr32.exe, расположенный в каталоге SysWOW64: C:\Windows\SysWOW64\regsvr32.exe "C:\PathToLibrary\DebenuPDFLibraryAX1113.dll"
  3. В коде обычной формы укажем ProgID 32-битной библиотеки:
    
    Процедура Подписать()
        Попытка
            PDF = Новый COMОбъект("DebenuPDFLibraryAX1113.PDFLibrary");
        Исключение
            Сообщить("Ошибка инициализации 32-битной библиотеки: " + ОписаниеОшибки());
            Возврат;
        КонецПопытки;
    КонецПроцедуры
    

Вариант 2: Вынос создания COM-объекта в серверный общий модуль

Если 32-битная библиотека отсутствует, а в наличии есть только 64-битная компонента, установленная на 64-битном сервере 1С, вызовем ее из обычной формы через серверный контекст конфигурации.

  1. Создадим новый общий модуль (например, ИнтеграцияPDFСервер) или используем существующий со следующими свойствами:
    • Сервер — флаг установлен;
    • Вызов сервера — флаг установлен;
    • Клиент (обычное приложение) — флаг снят.
  2. В общем модуле опишем экспортную процедуру или функцию, которая выполнит всю работу с 64-битным COM-объектом непосредственно на сервере:
    
    // В общем модуле ИнтеграцияPDFСервер
    Функция ОбработатьДокументНаСервере(ДвоичныеДанныеФайла) Экспорт
        
        Попытка
            PDF = Новый COMОбъект("DebenuPDFLibrary64AX1113.PDFLibrary");
        Исключение
            ВызватьИсключение "Не удалось инициализировать 64-битную библиотеку на сервере: " + ОписаниеОшибки();
        КонецПопытки;
        
        // Выполняем необходимые операции с файлом внутри сервера
        // ...
        
        Возврат Истина;
        
    КонецФункции
    
  3. В модуле обычной формы вызовем эту функцию общего модуля:
    
    Процедура Подписать()
        
        Попытка
            Результат = ИнтеграцияPDFСервер.ОбработатьДокументНаСервере(ДвоичныеДанныеФайла);
        Исключение
            Сообщить(ОписаниеОшибки());
        КонецПопытки;
        
    КонецПроцедуры
    

Важное ограничение: Сам экземпляр COMОбъект нельзя вернуть из серверной функции в модуль обычной формы (COM-объекты не сериализуются между клиентом и сервером). Вся обработка документа должна происходить внутри серверного вызова, а на клиент следует возвращать только готовый результат (число, строку, структуру или ДвоичныеДанные).

Вариант 3: Настройка COM+ приложения (DllSurrogate)

Если необходимо использовать 64-битную DLL из 32-битного клиента локально на одной машине без использования серверного кластера 1С, настроим системный суррогатный процесс Windows.

  1. Откроем оснастку «Службы компонентов» (команда dcomcnfg через строку «Выполнить»).
  2. Перейдем в раздел Компьютеры -> Мой компьютер -> Приложения COM+.
  3. Создадим новое приложение: выберем тип Серверное приложение и укажем учетную запись, под которой оно будет работать.
  4. В созданное приложение в ветку Компоненты добавим нужную 64-битную DLL.
  5. При вызове Новый COMОбъект(...) операционная система автоматически запустит отдельный процесс dllhost.exe требуемой разрядности и выполнит маршалинг вызовов между 32-битной 1С и 64-битной библиотекой.

Вариант 4: Использование консольных утилит (CLI) или Native API

Проанализируем альтернативные варианты, если работа через COM вызывает системные конфликты разрядностей:

  1. Запуск через командную строку: Если утилита или библиотека поставляется с исполняемым файлом (.exe), запустим его через метод ЗапуститьПриложение() или КомандаСистемы(). 32-битный клиент 1С может без ограничений запускать 64-битные исполняемые файлы .exe.
  2. Внешние компоненты Native API: Использование внешних компонент 1С, скомпилированных по технологии Native API. Они подключаются методом ПодключитьВнешнююКомпоненту() и обеспечивают прямую кроссплатформенную работу без использования механизмов Windows COM/OLE.
← На главную