Почему Native-компонента 1С работает на Windows 10, но не запускается на Windows Server 2012?

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

Разработка Native-компонент (ВК) для 1С:Предприятия с использованием C++ в среде Microsoft Visual Studio нередко сопровождается ситуацией, когда на рабочей станции разработчика под управлением Windows 10 библиотека загружается и выполняется штатно, а при переносе на Windows Server 2012 вызов метода ПодключитьВнешнююКомпоненту завершается ошибкой или библиотека вовсе не инициализируется. Разберем основные причины такого поведения и пошагово настроим параметры компиляции и серверную среду.

Причина 1. Зависимости от динамических библиотек C++ Runtime (CRT)

Выясним причину различий в поведении операционных систем. В клиентской Windows 10 библиотеки среды выполнения Visual C++ (vcruntime140.dll, msvcp140.dll) и компоненты Universal CRT (набор библиотек api-ms-win-crt-*.dll) почти всегда установлены по умолчанию или обновлены системой. В базовых образах Windows Server 2012 эти компоненты могут отсутствовать.

Если проект скомпилирован с динамической линковкой (флаг /MD), при попытке загрузки DLL платформа 1С не сможет найти нужные системные вызовы. Решить проблему можно двумя путями:

  1. Статическая линковка CRT (рекомендуемый вариант): включим все необходимые зависимости непосредственно в исполняемый файл компоненты. Для этого откроем свойства проекта C++ в Visual Studio: Свойства конфигурации -> C/C++ -> Создание кода (Code Generation) -> Библиотека времени выполнения (Runtime Library) и переключим значение на Многопоточная (/MT) для конфигурации Release (вместо «Многопоточная библиотека DLL (/MD)»). При такой сборке компонента не требует наличия сторонних runtime-библиотек на целевом сервере.
  2. Установка пакетов распространяемых компонентов: если статическая линковка не подходит, установим на Windows Server 2012 актуальный пакет Visual C++ Redistributable 2015–2022 (как x86, так и x64), а также накопительные обновления операционной системы, включающие Universal C Runtime (KB2999226 / KB2919355).

Причина 2. Ошибки компоновщика при попытке занизить версию подсистемы

Посмотрим на ошибку сборки, которая часто возникает при попытке адаптировать проект под старые ОС:

warning MSB8030: The linker switch "Minimum Required Version" requires "SubSystem" to be set... fatal error LNK1104: не удается открыть файл ",5.01"

Проанализируем ситуацию: данная ошибка линковщика возникает, если в свойствах проекта указана минимальная требуемая версия системы (например, 5.01 для Windows XP), но не определен сам тип целевой подсистемы. В результате линковщик неверно формирует строку параметров командной строки.

Разберем по шагам, как правильно настроить параметры сборки в Visual Studio:

  1. Перейдем в Свойства проекта -> Свойства конфигурации -> Общие. Для работы на Windows Server 2012 и выше занижать Набор инструментов платформы (Platform Toolset) до устаревших версий (вроде v140_xp) не требуется — оставим стандартный Visual Studio 2015 (v140) или более актуальный.
  2. Перейдем в раздел Свойства конфигурации -> Компоновщик (Linker) -> Система (System).
  3. Убедимся, что параметр Подсистема (SubSystem) установлен в значение Windows (/SUBSYSTEM:WINDOWS) или оставлен пустым по умолчанию для динамических библиотек (DLL).
  4. Поле Минимальная требуемая версия (Minimum Required Version) очистим, чтобы линковщик применил корректные значения по умолчанию для выбранной платформы.

Причина 3. Несоответствие разрядности (32-bit vs 64-bit) процесса 1С

Рассмотрим еще один важный фактор: разрядность скомпилированной динамической библиотеки должна строго соответствовать разрядности процесса, выполняющего загрузку.

  1. Если компонента подключается на клиенте, разрядность DLL должна совпадать с разрядностью установленного тонкого/толстого клиента 1С.
  2. Если метод ПодключитьВнешнююКомпоненту вызывается на стороне сервера («НаСервере»), библиотека загружается процессом рабочего процесса кластера 1С:Предприятия (rphost.exe). Если сервер 1С 64-разрядный, а скомпилирована была только 32-разрядная DLL (x86), подключение завершится ошибкой.

Для универсального решения сформируем архив внешней компоненты с файлом-манифестом manifest.xml, в котором опишем модули под разные платформы и архитектуры:


<bundle>
    <component os="Windows" path="MyComponent32.dll" type="native" arch="i386"/>
    <component os="Windows" path="MyComponent64.dll" type="native" arch="x86_64"/>
</bundle>

При использовании такого zip-архива платформа 1С автоматически извлечет и подключит требуемую библиотеку под нужную битность процесса.

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

Если код выполняется на сервере, проверим права доступа учетной записи службы 1С (по умолчанию USR1CV8):

  1. У службы должны быть права на чтение и выполнение в каталоге расположения компоненты, а также полные права на запись во временную директорию профиля пользователя службы (%TEMP%), куда платформа распаковывает вложения.
  2. Если DLL передавалась по сети или через интернет, операционная система Windows Server могла присвоить файлу статус заблокированного. Откроем свойства файла DLL через Проводник и, при наличии отметки «Осторожно: этот файл получен с другого компьютера», установим флажок Разблокировать (Unblock).
  3. Проверим наличие реализации обязательных экспортируемых функций в C++ коде Native-компоненты: GetClassObject, DestroyObject, GetClassNames и SetPlatformCapabilities.
← На главную