Как создать и внедрить внешнюю компоненту для 1С под Windows x86 и x64

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

При разработке сложных систем на платформе 1С часто возникает необходимость расширить стандартный функционал с помощью внешних компонент. Одной из наиболее актуальных задач является создание универсальной компоненты, которая будет корректно работать как на 32-битных клиентских местах (тонкий клиент), так и на 64-битных серверах (процесс rphost). В этой статье мы подробно разберем процесс создания такой компоненты с использованием Visual Studio и технологии Native API.

Определяем архитектуру проекта в Visual Studio

Для начала разберем важный технический момент: как заставить проект компилироваться под разные операционные системы и разрядности. Платформа 1С может работать в разных режимах, и разрядность компоненты (DLL) должна строго соответствовать разрядности процесса, который её вызывает. Если у пользователя установлен 32-битный тонкий клиент, ему нужна 32-битная библиотека. Если код выполняется на стороне сервера 1С (64-битного), потребуется 64-битная версия.

Разберем по шагам настройку в Visual Studio:

  1. Откроем «Диспетчер конфигураций» (Configuration Manager).
  2. В колонке «Платформа активного решения» выберем «Создать».
  3. Выберем x64 для создания 64-битной версии компоненты. Для 32-битной версии обычно используется x86 или Win32.
  4. Важная настройка компиляции: Перейдем в свойства проекта: Свойства -> C/C++ -> Создание кода -> Библиотека времени выполнения. Установим значение Многопоточная (/MT). Это позволит включить все необходимые зависимости Microsoft Visual C++ в саму DLL. В противном случае ваша компонента не запустится на компьютерах, где не установлен пакет Visual C++ Redistributable.

Реализация интерфейса Native API

При использовании шаблонов с ИТС мы сталкиваемся с необходимостью реализации обязательных методов. Проанализируем структуру методов CallAsProc и CallAsFunc. Если ваша компонента должна выполнять действие (например, инициализировать перехват печати) и возвращать результат, мы используем CallAsFunc. Если же возвращаемое значение не требуется — пишем код в CallAsProc.

Проанализируем ситуацию, когда метод не используется. Просто удалить его из кода нельзя, так как это нарушит структуру виртуальной таблицы объектов C++. В этом случае следует оставить пустую реализацию, которая возвращает false или код ошибки ADDIN_E_NOTIMPL.

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


// Пример использования IMemoryManager для выделения памяти под строку
wchar_t* dest = nullptr;
if (m_iMemory->AllocMemory((void**)&dest, (strLen + 1) * sizeof(wchar_t))) 
{
    wcscpy(dest, sourceString);
    // Теперь этот указатель можно безопасно передать в 1С
}

Помним, что платформа 1С работает со строками в формате UTF-16 (тип wchar_t в C++), поэтому при преобразовании данных из системных функций Windows нужно быть внимательными с кодировками.

Создание манифеста и упаковка в ZIP

Чтобы 1С понимала, какую именно библиотеку загружать, нам не нужно создавать разные макеты в конфигурации под каждую ОС. Правильный подход — использование единого архива с файлом манифеста. Выясним, как должна выглядеть структура ZIP-файла:

Разберем структуру файла Manifest.xml. Этот файл является связующим звеном:


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

Здесь атрибут project="i386" указывает на 32-битную версию, а project="x86_64" — на 64-битную. Платформа 1С автоматически прочитает этот файл и выберет нужный файл DLL в зависимости от окружения, в котором запущен сеанс.

Интеграция компоненты в 1С:Предприятие

После того как архив готов, переходим в конфигуратор 1С. Создадим общий макет с типом Двоичные данные и назовем его, например, КомпонентаПерехватаПечати. Загрузим в него наш созданный ZIP-архив.

Теперь разберем программный код для подключения компоненты. Использование метода СистемнаяИнформация для ручного определения ОС, как предлагалось в обсуждении, является избыточным при наличии манифеста. Платформа сделает это за нас.

Рассмотрим правильный алгоритм подключения:


// 1. Установка компоненты из макета во временное хранилище пользователя
РезультатУстановки = УстановитьВнешнююКомпоненту("ОбщийМакет.КомпонентаПерехватаПечати");

Если РезультатУстановки Тогда
    // 2. Подключение компоненты. Имя "MyComponent" используется для обращения к объекту
    ПодключитьВнешнююКомпоненту("ОбщийМакет.КомпонентаПерехватаПечати", "PrintHook", ТипВнешнейКомпоненты.Native);
    
    // 3. Создание объекта
    ОбъектКомпоненты = Новый("ВнешняяКомпонента.PrintHook");
Иначе
    Сообщить("Не удалось установить компоненту");
КонецЕсли;

Важный нюанс: Если вы планируете перехватывать печать из окна предварительного просмотра (интерфейсная задача), подключать компоненту нужно НаКлиенте. Если же компонента должна выполнять вычисления на сервере, вызов должен происходить в серверном контексте.

Решение задачи перехвата печати

Задача автора по перехвату печати из формы «Предварительный просмотр» является нетривиальной. Стандартное Native API 1С не имеет встроенных событий для отслеживания кликов по кнопкам в системных диалогах платформы. Для реализации этой логики внутри C++ кода компоненты обычно используются возможности Windows API:

  1. Использование хуков: Функция SetWindowsHookEx позволяет отслеживать сообщения в очередях событий окон. Это позволяет «поймать» момент нажатия кнопки «Печать».
  2. Мониторинг очереди печати: Использование Print Spooler API для отслеживания появления новых заданий на печать, инициированных процессом 1cv8.exe.

Проанализируем риски: работа с хуками требует глубокого понимания потоков Windows. Поскольку компонента загружается прямо в процесс 1С, любая критическая ошибка в C++ коде приведет к немедленному закрытию (аварийному завершению) всей программы 1С. Поэтому всегда используйте блоки try...catch и тщательно проверяйте указатели на nullptr.

Отладка внешней компоненты

Многие начинающие разработчики задаются вопросом: как проверить работу кода, если 1С уже запущена? Для этого в Visual Studio предусмотрен механизм Attach to Process (Отладка -> Присоединиться к процессу):

После присоединения вы сможете расставлять точки останова (breakpoints) прямо в коде C++, и при вызове метода из 1С отладчик остановит выполнение на нужной строке. Это значительно ускоряет поиск ошибок и проверку логики работы с памятью.

Таким образом, мы проанализировали полный цикл создания внешней компоненты: от настройки проекта и выбора архитектуры до упаковки в манифест и загрузки в конфигурацию 1С. Соблюдение этих правил обеспечит стабильную работу вашего расширения в любых клиент-серверных окружениях.

← На главную