Почему внешняя компонента Native API подключается на клиенте, но не работает на сервере 1С?

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

При разработке механизмов печати этикеток или генерации штрихкодов программисты часто сталкиваются с ситуацией, когда внешняя компонента (например, Zint или специализированные библиотеки печати) прекрасно работает в тонком клиенте, но отказывается инициализироваться на стороне сервера. Рассмотрим подробно, почему это происходит, и как правильно настроить среду для корректной работы ПодключитьВнешнююКомпоненту в обоих режимах.

Различие технологий: Native API против COM

Прежде всего, проанализируем ситуацию с регистрацией библиотек. Часто разработчики пытаются использовать утилиту regsvr32 для регистрации DLL, которая была написана по технологии Native API. В процессе выполнения этой команды возникает ошибка: "Не обнаружена точка входа". Это нормальное поведение.

Разберем причину: компоненты Native API не являются COM-объектами. Их не нужно регистрировать в реестре Windows. Платформа 1С загружает их напрямую в адресное пространство своего процесса (будь то 1cv8.exe клиента или rphost.exe сервера). Поэтому попытки зарегистрировать такие файлы через командную строку бессмысленны. Если компонента подключается на клиенте через ПодключитьВнешнююКомпоненту, значит, с самой библиотекой всё в порядке, и проблема кроется в окружении сервера.

Проблема разрядности (32-бит против 64-бит)

Наиболее вероятная причина, по которой один способ подключения работает на сервере, а другой — нет, заключается в разрядности (архитектуре) процесса. Посмотрим на ситуацию внимательнее:

  1. Тонкий клиент на Windows чаще всего является 32-битным приложением. Он легко загружает 32-битные библиотеки.
  2. Сервер 1С (rphost) в современных реалиях почти всегда 64-битный.

Проанализируем пример из темы: первая компонента имеет в названии Windows64, и она успешно подключается на сервере. Вторая компонента (Zint) работает только на клиенте. Это явный признак того, что библиотека Zint скомпилирована под архитектуру x86 (32 бита). 64-битный процесс сервера физически не может загрузить 32-битную DLL. В этом случае метод ПодключитьВнешнююКомпоненту на сервере всегда будет возвращать Ложь. В качестве альтернативы серверной библиотеке можно использовать внешний сервис генерации штрихкодов для 1С.

Использование универсального макета с манифестом

Для того чтобы система автоматически выбирала нужную версию библиотеки в зависимости от среды исполнения, рекомендуется использовать Общий макет типа "Двоичные данные", в который помещен ZIP-архив с манифестом. Разберем структуру такого архива по шагам:

Создадим архив, содержащий следующие файлы:

В файле 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). Выясним, есть ли у этого пользователя права на:

Если прав недостаточно, процесс rphost не сможет физически сохранить и запустить библиотеку, что приведет к отказу в подключении.

Итоговые рекомендации

Чтобы гарантированно решить проблему из обсуждения, выполните следующие действия:

  1. Убедитесь, что для компоненты Zint у вас есть 64-битная версия DLL. Без неё работа на стандартном 64-битном сервере 1С невозможна.
  2. Упакуйте обе версии (32 и 64 бит) в один ZIP-архив с корректным manifest.xml.
  3. Поместите этот архив в Общий макет.
  4. Используйте прямое подключение на сервере без предварительного вызова УстановитьВнешнююКомпоненту.
  5. Проверьте наличие необходимых Runtime-библиотек (VC++) на сервере.

При соблюдении этих условий механизм ПодключитьВнешнююКомпоненту будет отрабатывать стабильно независимо от того, вызывается ли он из тонкого клиента или из серверного контекста общего модуля.

← На главную