Как подключить библиотеку C# к 1С 7.7 и в чем разница между COM-объектом и внешней компонентой?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При интеграции платформы 1С 7.7 со сторонними библиотеками на платформе .NET разработчики часто сталкиваются с ошибками вида отсутствует CLSID или отсутствует интерфейс IInitDone. Выясним причину этой проблемы: в 1С 7.7 существует принципиальная разница между специализированной Внешней Компонентой (ВК) и стандартным COM-объектом (ActiveX/Automation).

Когда разработчик пишет обычный класс на C# и пытается подключить его методом ЗагрузитьВнешнююКомпоненту() или ПодключитьВнешнююКомпоненту(), 1С ожидает найти реализацию строгих внутренних интерфейсов платформы (таких как IInitDone, ILanguageExtender). Если этих интерфейсов в библиотеке нет, платформа выдает ошибку. Разберем по шагам, как правильно оформить и подключить библиотеку C# к 1С 7.7, а также рассмотрим альтернативные способы выполнения XSLT-трансформации.

Способ 1. Реализация библиотеки как COM-объекта (рекомендуемый)

Если перед нами стоит задача выполнить прикладные расчеты или преобразования (например, трансформацию XML), реализовывать сложный интерфейс внешней компоненты IInitDone нет никакой необходимости. Достаточно экспортировать класс C# как стандартный COM-сервер и обращаться к нему через обычный метод 1С СоздатьОбъект().

Проанализируем требования к исходному коду на C#:

  1. Класс должен иметь явный открытый конструктор без параметров.
  2. Все методы, принимающие или возвращающие параметры, должны использовать COM-совместимые типы (строки, числа, даты, массивы). Передавать внутренние типы .NET (такие как XmlDocument) напрямую в 1С 7.7 нельзя.
  3. Нельзя использовать интерактивные методы консоли (Console.WriteLine, Console.ReadLine), так как 1С 7.7 запускается в оконном режиме GUI и не имеет консольного ввода-вывода. Попытка вызвать чтение из консоли может привести к глухому зависанию программы.
  4. Классу и интерфейсу необходимо назначить атрибуты видимости COM и уникальные идентификаторы GUID.

Посмотрим на пример правильной реализации класса на C#:


using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Xml;
using System.Xml.Xsl;

namespace MyXsltLib
{
    [Guid("68F9ECEF-B19A-4F8B-AE0F-47B16180D52C")]
    [ComVisible(true)]
    public interface ITransform
    {
        string StartTest();
        string DoTransform(string xmlFilePath, string xsltFilePath);
    }

    [Guid("F62AA00E-235B-488C-BD81-D7A8470B3EDF")]
    [ProgId("MyXsltLib.Transform")]
    [ClassInterface(ClassInterfaceType.None)]
    [ComVisible(true)]
    public class Transform : ITransform
    {
        public Transform()
        {
        }

        public string StartTest()
        {
            return "Тестирование прошло успешно";
        }

        public string DoTransform(string xmlFilePath, string xsltFilePath)
        {
            XslCompiledTransform xslt = new XslCompiledTransform();
            xslt.Load(xsltFilePath);

            using (StringWriter writer = new StringWriter())
            {
                using (XmlReader reader = XmlReader.Create(xmlFilePath))
                {
                    xslt.Transform(reader, null, writer);
                }
                return writer.ToString();
            }
        }
    }
}

Разберем процесс сборки и регистрации компоненты в операционной системе:

  1. Разрядность сборки: Платформа 1С:Предприятие 7.7 является строго 32-битным приложением (x86). В свойствах проекта Visual Studio на вкладке «Сборка» (Build) необходимо явно указать целевую платформу: x86 (или Any CPU с отключенной опцией Prefer 32-bit). Сборка под x64 в 1С 7.7 работать не будет.
  2. Регистрация через RegAsm: Запускаем командную строку от имени Администратора. Регистрацию нужно выполнять утилитой regasm.exe строго из 32-разрядного каталога .NET Framework, добавив параметры /codebase и /tlb для экспорта библиотеки типов:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe /codebase /tlb "C:\PathToDll\MyXsltLib.dll"

Теперь обратимся к библиотеке из кода 1С 7.7. Обратите внимание: команды ЗагрузитьВнешнююКомпоненту() и ПодключитьВнешнююКомпоненту() здесь не используются. Создание происходит напрямую по зарегистрированному идентификатору ProgId:


Перем Трансформер, Результат;

Попытка
    Трансформер = СоздатьОбъект("MyXsltLib.Transform");
Исключение
    Сообщить("Не удалось создать COM-объект MyXsltLib.Transform: " + ОписаниеОшибки(), "!");
    Возврат;
КонецПопытки;

// Проверяем работу метода
Сообщить(Трансформер.StartTest());

// Выполняем XSLT-преобразование
Результат = Трансформер.DoTransform("D:\1.xml", "D:\3.xsl");
Сообщить("Преобразование завершено, длина ответа: " + СтрДлина(Результат));

Способ 2. Выполнение XSLT штатными средствами Windows без написания DLL

Рассмотрим подробнее задачу трансформации XML. Для применения шаблонов XSLT не обязательно разрабатывать собственную сборку на C#. В составе операционной системы Windows уже присутствует мощный COM-парсер MSXML2.DOMDocument, который штатно поддерживается в 1С 7.7.

Посмотрим на пример выполнения преобразования напрямую из встроенного языка 1С 7.7:


Перем XMLДок, XSLДок, РезультатТрансформации;

XMLДок = СоздатьОбъект("MSXML2.DOMDocument.6.0");
XMLДок.async = 0;
XMLДок.resolveExternals = 0;

Если XMLДок.load("D:\1.xml") = 0 Тогда
    Сообщить("Ошибка загрузки XML: " + XMLДок.parseError.reason, "!");
    Возврат;
КонецЕсли;

XSLДок = СоздатьОбъект("MSXML2.DOMDocument.6.0");
XSLДок.async = 0;
XSLДок.resolveExternals = 0;

Если XSLДок.load("D:\3.xsl") = 0 Тогда
    Сообщить("Ошибка загрузки XSLT: " + XSLДок.parseError.reason, "!");
    Возврат;
КонецЕсли;

// Выполняем трансформацию
РезультатТрансформации = XMLДок.transformNode(XSLДок);
Сообщить("Результат успешно получен:");
Сообщить(РезультатТрансформации);

Способ 3. Вызов отдельного консольного приложения

Если логика на C# сложна или на рабочих станциях пользователей ограничены права администратора (из-за чего нельзя зарегистрировать библиотеку в реестре утилитой regasm), можно скомпилировать проект как исполняемый файл (.exe). Запуск такого приложения из 1С выполняется через объект WScript.Shell с ожиданием завершения процесса:


Перем WshShell, КоманднаяСтрока, КодВозврата;

WshShell = СоздатьОбъект("WScript.Shell");
КоманднаяСтрока = """C:\PathToApp\XsltConverter.exe"" ""D:\1.xml"" ""D:\3.xsl"" ""D:\out.xml""";

// Третий параметр 1 означает ожидание завершения работы утилиты
КодВозврата = WshShell.Run(КоманднаяСтрока, 0, 1);

Если КодВозврата = 0 Тогда
    Сообщить("Файл успешно преобразован!");
Иначе
    Сообщить("Произошла ошибка при выполнении конвертера. Код ошибки: " + КодВозврата, "!");
КонецЕсли;

Таким образом, если требуется взаимодействие через библиотеки типов, создавайте класс с атрибутами [ComVisible(true)] и подключайте его через СоздатьОбъект(). Если же задача ограничивается обработкой XML и XSLT, проще и надежнее использовать встроенный системный парсер MSXML2.DOMDocument.

← На главную