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

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

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

Анализ типовой ситуации

Рассмотрим стандартный сценарий: библиотека написана на C++ (например, в среде Visual Studio) с использованием шаблона Native API из документации 1С. В коде конфигурации для подключения компоненты из общего макета используется типовая конструкция:


&НаСервере
Функция ПодключитьСервернуюКомпоненту()
    Результат = ПодключитьВнешнююКомпоненту("ОбщийМакет.Компонента", "AddInNativeExtension", ТипВнешнейКомпоненты.Native);
    Если Не Результат Тогда
        ВызватьИсключение "Не удалось подключить внешнюю компоненту на сервере!";
    КонецЕсли;
    Возврат Результат;
КонецФункции

Если на клиентском рабочем месте этот код возвращает Истина, а на сервере вызов терпит неудачу, причина практически всегда кроется в одном из четырех факторов: ошибках в ZIP-архиве и файле manifest.xml, несовпадении разрядности процессов, нехватке системных библиотек в операционной системе сервера или ограничениях прав службы 1С.

Решение 1. Проверка структуры ZIP-архива и файла манифеста

Выясним главную причину сбоя при загрузке из общего макета — некорректное оформление ZIP-пакета. Платформа 1С строго валидирует состав архива перед извлечением динамических библиотек:

  1. Расположение файлов: Файл manifest.xml (или MANIFEST.XML) и скомпилированные библиотеки (.dll, .so) должны находиться строго в корне архива. Если при упаковке они оказались внутри вложенной папки, сервер 1С не сможет обнаружить манифест и завершит подключение с результатом Ложь.
  2. Кодировка манифеста: Файл манифеста должен быть сохранен в кодировке UTF-8 без BOM (Byte Order Mark). Серверный парсер XML может некорректно обрабатывать скрытые сигнатуры порядка байтов.
  3. Регистр и пути: Атрибут path в теге <component> должен в точности, с учетом регистра символов, совпадать с именем файла DLL в архиве.
  4. Архитектура и операционная система: Атрибуты должны соответствовать окружению сервера. Для 32-разрядного сервера 1С под Windows указывается os="Windows" и arch="i386", для 64-разрядного сервера — arch="x86_64".

Посмотрим на пример корректного файла manifest.xml, поддерживающего обе разрядности Windows-сервера:


<?xml version="1.0" encoding="UTF-8"?>
<bundle xmlns="http://v8.1c.ru/8.2/virtual-resource-system">
    <component os="Windows" type="native" path="Component32.dll" arch="i386"/>
    <component os="Windows" type="native" path="Component64.dll" arch="x86_64"/>
</bundle>

Решение 2. Проверка разрядности сервера 1С и динамических библиотек

Проанализируем разрядность серверного процесса 1С. Очень часто на 64-разрядную серверную ОС устанавливается 32-разрядный сервер 1С:Предприятие (или наоборот). Рабочий процесс rphost не сможет загрузить библиотеку, если ее битность отличается от битности самого процесса службы 1С.

  1. Определим разрядность запущенного процесса службы сервера (в Диспетчере задач Windows смотрим процесс rphost.exe — наличие суффикса *32 указывает на 32-битный процесс).
  2. Убедимся, что для 32-разрядного rphost.exe скомпилирована 32-битная DLL (архитектура Win32/x86), а для 64-разрядного — 64-битная (архитектура x64).

Решение 3. Устранение внешних зависимостей и настройка компиляции в Visual Studio

Разберем параметры сборки проекта на C++. Когда внешняя компонента собирается с динамической компоновкой среды выполнения C/C++ (флаг /MD), для ее работы на сервере требуются установленные пакеты Microsoft Visual C++ Redistributable соответствующей версии компилятора.

  1. Статическая линковка: В свойствах проекта C++ в Visual Studio перейдем в раздел C/C++ → Code Generation (Создание кода) → Runtime Library (Библиотека времени выполнения) и переключим параметр на Multi-threaded (/MT) вместо /MD. Это включит весь необходимый код рантайма внутрь DLL.
  2. Установка пакетов распространяемого компонента: Если статическая линковка не используется, установим на сервере соответствующий пакет vcredist_x86.exe или vcredist_x64.exe.
  3. Обновление универсальной среды выполнения: Для операционных систем Windows Server 2012 R2 и более ранних убедимся в наличии обновления Universal C Runtime (KB2999226).
  4. Экспорт функций: Проверим, что методы интерфейса компоненты (GetClassObject, DestroyObject, GetClassNames, SetPlatformCapabilities) объявлены с директивой extern "C" во избежание искажения имен (name mangling).

Решение 4. Права учетной записи службы 1С и политики безопасности

Рассмотрим ограничения со стороны операционной системы и кластера серверов 1С:

  1. Права к временным каталогам: Служба сервера 1С обычно запускается под пользователем USR1CV8. При подключении из макета сервер распаковывает DLL во временный каталог пользователя службы (%TEMP%). Пользователь USR1CV8 должен иметь полные права на запись и исполнение файлов в своем локальном профиле.
  2. Политики SRP и AppLocker: Убедимся, что на сервере групповыми политиками не запрещен запуск исполняемого кода и загрузка .dll из каталога временных файлов.
  3. Профили безопасности 1С: Если в информационной базе включен профиль безопасности кластера, по умолчанию запуск внешних компонент запрещен. В настройках профиля необходимо добавить явное разрешение на использование внешней компоненты.
  4. Безопасный режим: Если вызов происходит в фоновом задании, проверьте, чтобы для задания не был принудительно установлен безопасный режим, блокирующий подключение неутвержденных внешних модулей.

Решение 5. Использование режима изоляции процессов (начиная с платформы 8.3.18)

Для повышения надежности сервера 1С и безопасной отладки Native-компонент на сервере рекомендуется использовать четвертый параметр метода ПодключитьВнешнююКомпоненту — режим изоляции. Это позволяет запускать код C++ в отдельном системном процессе coreconnector, исключая падение рабочего процесса rphost при возможных сбоях в памяти DLL:


&НаСервере
Процедура ПодключитьИзолированно()
    Результат = ПодключитьВнешнююКомпоненту(
        "ОбщийМакет.Компонента", 
        "AddInNativeExtension", 
        ТипВнешнейКомпоненты.Native, 
        РежимИзоляцииВнешнейКомпоненты.Индивидуальный
    );
    Если Результат Тогда
        ОбъектКомпоненты = Новый("AddIn.AddInNativeExtension.MyExtension");
    КонецЕсли;
КонецПроцедуры
← На главную