Как создать собственную компоненту для 1С без использования технологии внешних компонент (ТСВК)?

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

При разработке прикладных решений на платформе 1С часто возникает необходимость использовать сторонние системные библиотеки, такие как Scripting.Dictionary, VBScript.RegExp или объекты MS Office. Эти библиотеки не реализуют специализированные интерфейсы 1С (ТСВК), но без проблем создаются через стандартный вызов Новый COMОбъект(). Разберем, как разработать собственный компонент общего назначения, который можно использовать не только в 1С, но и в любых других Windows-приложениях.

Разница между технологией внешних компонент 1С и классическим COM

Проанализируем ситуацию: для взаимодействия внешнего кода с платформой 1С существуют два принципиально разных подхода:

  1. Внешняя компонента 1С (ТСВК / Native API / COM-обертка ТСВК): Библиотека должна реализовывать специальные интерфейсы платформы (например, IInitDone, ILanguageExtender). Такие компоненты подключаются методами ПодключитьВнешнююКомпоненту(), поддерживают генерацию внешних событий в 1С через ВнешнееСобытие и могут инкапсулироваться внутри макетов конфигурации.
  2. Обычный COM-объект (Automation Server): Библиотека общего назначения, зарегистрированная в операционной системе Windows. Ей не требуется знать ничего о платформе 1С. Взаимодействие происходит по протоколу OLE Automation через стандартный интерфейс IDispatch. Создание такого объекта выполняется конструктором Новый COMОбъект("ИмяКласса") (или СоздатьОбъект() в 1С 7.7).

Если вам требуется создать универсальный модуль (например, для сложных математических вычислений, интеграции с нестандартным оборудованием или парсинга), достаточно написать классический COM-сервер.

Требования платформы 1С к COM-объектам

Рассмотрим подробнее технические ограничения и условия, необходимые для корректной работы стороннего COM-объекта в 1С:

  1. Обязательная поддержка интерфейса IDispatch: Платформа 1С работает с COM-объектами исключительно через механизм позднего связывания (Late Binding). Класс обязан предоставлять интерфейс IDispatch (или Dual-интерфейс). Чистые виртуальные таблицы методов (vtable) платформой не поддерживаются.
  2. Совместимость типов данных: Все методы и свойства должны принимать и возвращать типы, совместимые со структурой VARIANT (строки BSTR, целые и вещественные числа, даты VT_DATE, логические значения VT_BOOL, массивы SAFEARRAY или ссылки IDispatch).
  3. Поддержка перебора коллекций: Если ваш класс представляет собой список или коллекцию и вы хотите обходить его стандартным циклом Для Каждого Элемент Из Коллекция Цикл, объект должен реализовывать скрытый метод _NewEnum с идентификатором DISPID_NEWENUM (значение -4), возвращающий интерфейс IEnumVARIANT.

Создание COM-компоненты на C#: пошаговый пример

Разберем по шагам создание простого COM-сервера на языке C#. Для обеспечения корректного позднего связывания опишем интерфейс и реализующий его класс с явным указанием GUID:


using System;
using System.Runtime.InteropServices;

namespace MyCustomLib
{
    [Guid("364C5E66-4412-48E3-8BD8-7B2BF09E8922")]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    [ComVisible(true)]
    public interface ICalculator
    {
        int Sum(int a, int b);
        string GetVersion();
    }

    [Guid("8C034F6A-1D3F-4DB8-BC99-B73873D8C297")]
    [ProgId("MyCustomLib.Calculator")]
    [ClassInterface(ClassInterfaceType.None)]
    [ComVisible(true)]
    public class Calculator : ICalculator
    {
        public int Sum(int a, int b)
        {
            return a + b;
        }

        public string GetVersion()
        {
            return "1.0.0";
        }
    }
}

Посмотрим на ключевые атрибуты в примере:

  1. [ComVisible(true)] — делает типы видимыми для COM-клиентов.
  2. [ProgId("...")] — задает строковый идентификатор класса (ProgID), который будет использоваться в 1С при вызове.
  3. [InterfaceType(ComInterfaceType.InterfaceIsDual)] — гарантирует поддержку IDispatch.
  4. [ClassInterface(ClassInterfaceType.None)] — отключает автоматическую генерацию интерфейса класса, обязывая использовать явно объявленный контракт ICalculator.

Сборка и регистрация библиотеки в системе

Выясним причину, почему собранную библиотеку нужно регистрировать перед вызовом. Windows должна знать, в какой DLL находится запрашиваемый ProgID.

В зависимости от используемой версии платформы .NET регистрация выполняется следующим образом:

  1. Для классического .NET Framework: В свойствах проекта активируйте флаг «Регистрация для COM-взаимодействия» (Register for COM interop) или выполните регистрацию через командную строку утилитой regasm MyCustomLib.dll /codebase /tlb.
  2. Для современного .NET (.NET 6 / 8 / 9): В файле проекта .csproj добавьте параметр <EnableComHosting>true</EnableComHosting>. При сборке будет сформирован файл MyCustomLib.comhost.dll, который регистрируется через стандартную системную утилиту Windows: regsvr32 MyCustomLib.comhost.dll.

Использование созданного объекта в коде 1С

После успешной регистрации библиотеки в операционной системе объект становится доступен в коде 1С. Посмотрим на пример вызова:


Попытка
    Калькулятор = Новый COMОбъект("MyCustomLib.Calculator");
    
    Результат = Калькулятор.Sum(15, 27);
    Версия    = Калькулятор.GetVersion();
    
    Сообщить("Результат сложения: " + Результат);
    Сообщить("Версия компоненты: " + Версия);
Исключение
    Сообщить("Не удалось создать COM-объект: " + ОписаниеОшибки(), СтатусСообщения.Важное);
КонецПопытки;

Важные системные нюансы при эксплуатации

Проанализируем практические сложности, с которыми можно столкнуться при использовании COM-объектов:

  1. Несовпадение разрядности (32 и 64 бит): 32-битный клиентский процесс 1С (1cv8c.exe) не может загрузить 64-битную COM DLL, и наоборот. Если разрядности сервера 1С или клиента не совпадают с библиотекой, ее следует настроить как серверное приложение в оснастке «Службы компонентов» (DCOM/COM+). В этом случае библиотека исполняется внутри процесса dllhost.exe и доступна из приложений любой разрядности.
  2. Выполнение в серверном контексте: Если вызов Новый COMОбъект выполняется в процедуре «НаСервере» или в фоновом задании, убедитесь, что у пользователя операционной системы, под которым работает служба сервера 1С (например, USR1CV8), есть права на чтение ветвей реестра и запуск соответствующей DLL.
  3. Альтернатива без COM: Если требуется полная кроссплатформенность (работа под Linux, macOS) и изоляция процессов от сбоев, логику компоненты можно оформить в виде отдельного легковесного сервиса и взаимодействовать с ним из 1С через встроенный объект HTTPСоединение.
← На главную