Интеграция сторонних библиотек, написанных на языке C# (.NET), в среду 1С:Предприятие через механизм COM (Component Object Model) — мощный инструмент для расширения стандартного функционала системы. Тем не менее этот процесс часто сопровождается трудностями настройки. Разработчики регулярно сталкиваются с двумя критическими проблемами:
В этой статье мы подробно разберем, почему возникают эти сбои, как правильно определить разрядность вашего приложения 1С, корректно зарегистрировать библиотеку в операционной системе и адаптировать код C# и 1С для стабильного взаимодействия.
Операционная система Windows x64 разделяет реестр и системные папки для 32-битных (x86) и 64-битных (x64) приложений. Если ваша библиотека зарегистрирована в 64-битном разделе реестра, а платформа 1С запущена как 32-битное приложение, то 1С физически не сможет найти и загрузить этот класс. Возникнет ошибка «Class not registered» (Класс не зарегистрирован).
Проанализируем ситуацию по шагам и выясним, как определить разрядность клиента 1С и правильно зарегистрировать DLL.
Самый надежный способ узнать разрядность работающего процесса 1С — проверить путь к каталогу исполняемых файлов платформы. Для этого в коде 1С (например, во внешней обработке) выполним следующий метод:
Сообщить(КаталогПрограммы());
Проанализируем возвращаемое значение:
C:\Program Files (x86)\1cv8\8.3.9.2033\bin\), это означает, что у вас запущен 32-битный (x86) клиент 1С.C:\Program Files\1cv8\...), то перед нами 64-битный (x64) клиент 1С.Для COM-видимых библиотек, написанных на .NET (C#), стандартная утилита regsvr32 не подходит. Регистрация должна выполняться с помощью специализированной утилиты RegAsm.exe (Assembly Registration Tool), которая поставляется вместе с .NET Framework.
В зависимости от разрядности клиента 1С (выявленной на предыдущем шаге), нам необходимо использовать строго определенную версию RegAsm.exe:
Вариант А: Если клиент 1С 32-битный (x86):
Используем утилиту из каталога Framework (32-бит):
C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe "C:\ПутьКПапке\Library.ComSdk.dll" /codebase /tlb
Вариант Б: Если клиент 1С 64-битный (x64):
Используем утилиту из каталога Framework64 (64-бит):
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe "C:\ПутьКПапке\Library.ComSdk.dll" /codebase /tlb
Важные параметры запуска утилиты:
/codebase обязателен к использованию. Он прописывает в реестре Windows прямой физический путь к вашей DLL. Без этого ключа операционная система будет искать библиотеку только в глобальном кэше сборок (GAC - Global Assembly Cache), и если её там нет, вы получите ошибку «The system cannot find the file specified» (Не удается найти указанный файл)./tlb генерирует и регистрирует библиотеку типов (Type Library), что необходимо для корректного маршалинга типов между управляемым кодом .NET и неуправляемым кодом 1С.Перед повторной правильной регистрацией обязательно удалите старую некорректную регистрацию с помощью ключа /u. Например:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe /u "C:\ПутьКПапке\Library.ComSdk.dll"
---
Рассмотрим ситуацию, когда первая проблема решена: объект успешно создается через конструктор Новый COMОбъект, однако при попытке вызвать любой метод объекта (например, Initialize) система выдает «Ошибка при вызове метода контекста (Initialize): Неизвестная ошибка». При этом аналогичный код в скриптовых движках, таких как OneScript, может выполняться без каких-либо нареканий. Выясним фундаментальные причины такого поведения.
В отличие от OneScript и C#, среда исполнения 1С:Предприятие критически чувствительна к синтаксису вызова функций COM-объектов через интерфейс IDispatch (Late Binding / Позднее связывание).
Посмотрим на пример ошибочного кода в 1С:
pvService = Новый COMОбъект("Library.ComSdk.Service");
pvService.Initialize; // ОШИБКА! Вызов метода без скобок
settingService = pvService.GetSettingService; // ОШИБКА!
Когда вы пишете имя метода без круглых скобок, 1С пытается прочитать это имя как Свойство (Property) объекта, используя Get-аксессор. Так как в классе C# Initialize определен как метод (Method), а не как свойство, COM-сервер возвращает ошибку отсутствия члена группы, которую 1С интерпретирует для разработчика как абстрактную «Неизвестную ошибку».
Решение: Всегда явно указывайте круглые скобки при вызове любых методов COM-объекта в 1С, даже если они не принимают никаких параметров:
pvService = Новый COMОбъект("Library.ComSdk.Service");
pvService.Initialize(); // Правильно!
settingService = pvService.GetSettingService(); // Правильно!
Обратим внимание на вызов settingService = pvService.GetSettingService();. Данный метод возвращает другой объект (класс настроек). Чтобы этот вызов прошел успешно в 1С, возвращаемый класс также должен быть полностью подготовлен к работе через COM-соединение.
В исходном коде вашей C# библиотеки проверьте выполнение следующих правил:
public.[ComVisible(true)].Пример правильного оформления дочернего класса в C#:
[ComVisible(true)]
[Guid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class SettingService
{
public SettingService() { } // Конструктор по умолчанию
public string GetConfigPath()
{
return "C:\\Config\\config.xml";
}
}
Платформа 1С общается с COM-объектами строго в рамках стандартов типов OLE/COM. Она не умеет напрямую работать со специфичными для .NET типами данных. Если ваш C# метод возвращает:
List<T>, Dictionary<TKey, TValue>);struct);Task или Task<T>).В этом случае при попытке вызова метода 1С не сможет выполнить автоматическое преобразование типов (маршалинг) и вернет «Неизвестную ошибку». Спроектируйте интерфейс COM-библиотеки так, чтобы методы возвращали только простые типы (числа, строки, булево), стандартные массивы (Array) или другие COM-видимые классы.
Если ваша DLL внутри себя использует обращения к файлам настроек (например, считывает строки подключения к БД из app.config), то при запуске из-под 1С возникнет критическая ошибка. Процесс 1С (1cv8.exe) при инициализации .NET-библиотеки будет искать конфигурационный файл в своем собственном каталоге запуска (то есть файл 1cv8.exe.config в папке bin платформы 1С).
Не найдя нужных секций настроек, .NET-код внутри DLL выбросит исключение NullReferenceException или ConfigurationErrorsException, которое на уровне 1С превратится в «Неизвестную ошибку».
Решение: Избегайте использования стандартного ConfigurationManager в C# коде библиотек для 1С. Реализуйте явную загрузку конфигурационных файлов по абсолютному пути, определяя каталог, в котором физически расположена сама DLL:
string assemblyPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
string configPath = System.IO.Path.ChangeExtension(assemblyPath, ".config");
// Далее вручную парсируйте xml-файл настроек по пути configPath
---
Подводя итог, приведем пример надежного написания кода вызова C# библиотеки в среде 1С:Предприятие:
&НаКлиенте
Процедура ВыполнитьПодключение()
Попытка
// Инициализируем COM-объект
СервисСДК = Новый COMОбъект("Library.ComSdk.Service");
Исключение
ВызватьИсключение "Не удалось создать COM-объект. Проверьте разрядность платформы 1С и регистрацию DLL! Описание: " + ОписаниеОшибки();
КонецПопытки;
Попытка
// Вызов метода ОБЯЗАТЕЛЬНО со скобками
СервисСДК.Initialize();
// Получение дочерней службы (класс возвращаемого объекта должен быть ComVisible)
НастройкиСервиса = СервисСДК.GetSettingService();
ПутьКФайлу = НастройкиСервиса.GetConfigPath();
ПоказатьПредупреждение(, "Успешное подключение! Путь к конфигу: " + ПутьКФайлу);
Исключение
ВызватьИсключение "Ошибка взаимодействия с методами библиотеки: " + ОписаниеОшибки();
КонецПопытки;
КонецПроцедуры
Следуя этим шагам и правилам, мы гарантируем стабильное сопряжение программного кода на C# с бизнес-логикой на платформе 1С:Предприятие.