При интеграции 1С со сторонними библиотеками через технологию COM разработчики нередко сталкиваются с ситуацией, когда один и тот же код успешно выполняется в управляемой форме на сервере, но вызывает исключение «Ошибка при вызове конструктора (COMОбъект): Класс не зарегистрирован» при выполнении в модуле обычной формы. Разберем детально, почему это происходит и какими способами можно устранить проблему.
Рассмотрим типовой сценарий, в котором воспроизводится ошибка. В управляемой форме код выполняется с директивой &НаСервере:
&НаКлиенте
Процедура Подписать(Команда)
ПодписатьНаСервере();
КонецПроцедуры
&НаСервере
Процедура ПодписатьНаСервере()
Попытка
PDF = Новый COMОбъект("DebenuPDFLibrary64AX1113.PDFLibrary");
Исключение
Сообщить("Не зарегистрирована библиотека!");
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
КонецПроцедуры
При попытке перенести этот же вызов в модуль обычной формы возникает ошибка:
Процедура Подписать()
Попытка
PDF = Новый COMОбъект("DebenuPDFLibrary64AX1113.PDFLibrary");
Исключение
Сообщить("Не зарегистрирована библиотека!");
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
КонецПроцедуры
Выясним причину такого поведения платформы. Основной фактор здесь — несовпадение разрядности клиентского приложения 1С и регистрируемой COM-библиотеки.
rphost.exe) чаще всего развернута в 64-разрядном варианте (x64). При выполнении серверной процедуры управляемой формы 64-битный процесс сервера 1С без проблем загружает 64-битную COM-библиотеку.&НаСервере и &НаКлиенте в обычных формах недоступны.InprocServer32 DLL). При обращении к реестру 32-битный процесс ищет ProgID и CLSID в ветке WOW6432Node, где 64-битная библиотека не зарегистрирована. В результате платформа 1С возвращает системную ошибку о том, что класс не зарегистрирован.Рассмотрим практические варианты решения этой задачи в зависимости от архитектуры вашей системы.
Если логика должна гарантированно выполняться на стороне клиента, самым простым и надежным решением является установка и регистрация 32-разрядной версии COM-компоненты.
DebenuPDFLibraryAX1113.dll вместо версии с суффиксом 64).regsvr32.exe, расположенный в каталоге SysWOW64:
C:\Windows\SysWOW64\regsvr32.exe "C:\PathToLibrary\DebenuPDFLibraryAX1113.dll"
Процедура Подписать()
Попытка
PDF = Новый COMОбъект("DebenuPDFLibraryAX1113.PDFLibrary");
Исключение
Сообщить("Ошибка инициализации 32-битной библиотеки: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
КонецПроцедуры
Если 32-битная библиотека отсутствует, а в наличии есть только 64-битная компонента, установленная на 64-битном сервере 1С, вызовем ее из обычной формы через серверный контекст конфигурации.
ИнтеграцияPDFСервер) или используем существующий со следующими свойствами:
// В общем модуле ИнтеграцияPDFСервер
Функция ОбработатьДокументНаСервере(ДвоичныеДанныеФайла) Экспорт
Попытка
PDF = Новый COMОбъект("DebenuPDFLibrary64AX1113.PDFLibrary");
Исключение
ВызватьИсключение "Не удалось инициализировать 64-битную библиотеку на сервере: " + ОписаниеОшибки();
КонецПопытки;
// Выполняем необходимые операции с файлом внутри сервера
// ...
Возврат Истина;
КонецФункции
Процедура Подписать()
Попытка
Результат = ИнтеграцияPDFСервер.ОбработатьДокументНаСервере(ДвоичныеДанныеФайла);
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Важное ограничение: Сам экземпляр COMОбъект нельзя вернуть из серверной функции в модуль обычной формы (COM-объекты не сериализуются между клиентом и сервером). Вся обработка документа должна происходить внутри серверного вызова, а на клиент следует возвращать только готовый результат (число, строку, структуру или ДвоичныеДанные).
Если необходимо использовать 64-битную DLL из 32-битного клиента локально на одной машине без использования серверного кластера 1С, настроим системный суррогатный процесс Windows.
dcomcnfg через строку «Выполнить»).Новый COMОбъект(...) операционная система автоматически запустит отдельный процесс dllhost.exe требуемой разрядности и выполнит маршалинг вызовов между 32-битной 1С и 64-битной библиотекой.Проанализируем альтернативные варианты, если работа через COM вызывает системные конфликты разрядностей:
.exe), запустим его через метод ЗапуститьПриложение() или КомандаСистемы(). 32-битный клиент 1С может без ограничений запускать 64-битные исполняемые файлы .exe.ПодключитьВнешнююКомпоненту() и обеспечивают прямую кроссплатформенную работу без использования механизмов Windows COM/OLE.