При разработке механизмов печати этикеток или генерации штрихкодов программисты часто сталкиваются с ситуацией, когда внешняя компонента (например, Zint или специализированные библиотеки печати) прекрасно работает в тонком клиенте, но отказывается инициализироваться на стороне сервера. Рассмотрим подробно, почему это происходит, и как правильно настроить среду для корректной работы ПодключитьВнешнююКомпоненту в обоих режимах.
Прежде всего, проанализируем ситуацию с регистрацией библиотек. Часто разработчики пытаются использовать утилиту regsvr32 для регистрации DLL, которая была написана по технологии Native API. В процессе выполнения этой команды возникает ошибка: "Не обнаружена точка входа". Это нормальное поведение.
Разберем причину: компоненты Native API не являются COM-объектами. Их не нужно регистрировать в реестре Windows. Платформа 1С загружает их напрямую в адресное пространство своего процесса (будь то 1cv8.exe клиента или rphost.exe сервера). Поэтому попытки зарегистрировать такие файлы через командную строку бессмысленны. Если компонента подключается на клиенте через ПодключитьВнешнююКомпоненту, значит, с самой библиотекой всё в порядке, и проблема кроется в окружении сервера.
Наиболее вероятная причина, по которой один способ подключения работает на сервере, а другой — нет, заключается в разрядности (архитектуре) процесса. Посмотрим на ситуацию внимательнее:
Проанализируем пример из темы: первая компонента имеет в названии Windows64, и она успешно подключается на сервере. Вторая компонента (Zint) работает только на клиенте. Это явный признак того, что библиотека Zint скомпилирована под архитектуру x86 (32 бита). 64-битный процесс сервера физически не может загрузить 32-битную DLL. В этом случае метод ПодключитьВнешнююКомпоненту на сервере всегда будет возвращать Ложь. В качестве альтернативы серверной библиотеке можно использовать внешний сервис генерации штрихкодов для 1С.
Для того чтобы система автоматически выбирала нужную версию библиотеки в зависимости от среды исполнения, рекомендуется использовать Общий макет типа "Двоичные данные", в который помещен ZIP-архив с манифестом. Разберем структуру такого архива по шагам:
Создадим архив, содержащий следующие файлы:
Component32.dll (библиотека для 32-битного клиента);Component64.dll (библиотека для 64-битного сервера);manifest.xml (файл описания).В файле manifest.xml необходимо жестко прописать соответствие файлов платформам. Рассмотрим пример содержания манифеста:
<?xml version="1.0" encoding="UTF-8"?>
<bundle xmlns="http://v8.1c.ru/8.2/addin/bundle">
<component os="Windows" path="Component32.dll" type="native" arch="i386"/>
<component os="Windows" path="Component64.dll" type="native" arch="x86_64"/>
</bundle>
Когда вы вызываете ПодключитьВнешнююКомпоненту("ОбщийМакет.МояКомпонента", "Имя", ТипВнешнейКомпоненты.Native), платформа сама распакует архив, прочитает манифест и загрузит именно ту DLL, которая подходит под текущий процесс (клиентский или серверный). Разобраться в структуре и правильной сборке собственных библиотек поможет шаблон проекта внешней компоненты для 1С.
Выясним разницу между методами УстановитьВнешнююКомпоненту и ПодключитьВнешнююКомпоненту. Это часто вызывает путаницу у начинающих разработчиков.
Метод УстановитьВнешнююКомпоненту предназначен исключительно для клиента. Он копирует файлы компоненты из макета в локальный каталог пользователя на жестком диске. На сервере этот метод не работает и не требуется, так как сервер имеет доступ к макетам конфигурации напрямую. На сервере достаточно сразу вызывать метод подключения:
// Код для сервера
Результат = ПодключитьВнешнююКомпоненту("ОбщийМакет.Barcode", "Zint", ТипВнешнейКомпоненты.Native);
Если Не Результат Тогда
ЗаписьЖурналаРегистрации("Ошибка подключения компоненты на сервере", УровеньЖурналаРегистрации.Ошибка);
КонецЕсли;
Если разрядность совпадает (вы используете 64-битную компоненту на 64-битном сервере), но она все равно не подключается, проанализируем зависимости. Многие компоненты на C++ требуют наличия определенных версий Microsoft Visual C++ Redistributable.
На рабочих станциях пользователей эти библиотеки часто установлены "по умолчанию" вместе с другими программами. На серверных ОС среда выполнения может отсутствовать. Проверить зависимости DLL можно с помощью бесплатных утилит, таких как Dependencies или Detect It Easy. Если компоненте не хватает системной библиотеки (например, msvcp140.dll), она не загрузится, а 1С выдаст общую ошибку подключения.
При подключении компоненты на сервере 1С извлекает её из макета и сохраняет во временную папку пользователя, под которым запущена служба 1C:Enterprise 8.3 Server Agent (обычно это USR1CV8). Выясним, есть ли у этого пользователя права на:
%TEMP% серверного пользователя;Если прав недостаточно, процесс rphost не сможет физически сохранить и запустить библиотеку, что приведет к отказу в подключении.
Чтобы гарантированно решить проблему из обсуждения, выполните следующие действия:
manifest.xml.УстановитьВнешнююКомпоненту.При соблюдении этих условий механизм ПодключитьВнешнююКомпоненту будет отрабатывать стабильно независимо от того, вызывается ли он из тонкого клиента или из серверного контекста общего модуля.