Внешняя компонента 1С: подключение, методы и события

Дата: 21.09.2026 10:34:30
Интеграции
Внешние компоненты
Программирование 1С
Доработка 1С
Комментарий:
0
Платформа:
8.3
Конфигурация:
Любая
Формы:
Любые

Внешняя компонента 1С — библиотека, обычно на C++, которую платформа загружает в свой процесс и показывает встроенному языку как объект с методами, свойствами и событиями. Через неё 1С получает то, чего нет в платформе: системные API, нестандартные протоколы, быстрые алгоритмы, сторонние SDK. Ниже — полный цикл работы с ней на платформе 8.3, с кодом на каждом шаге. Сканеры и торговое оборудование разобраны отдельно, в статье про сканер штрихкода на Native API.

Примеры — для условной компоненты: ZIP в общем макете ДемоКомпонента, символическое имя Demo, объект Main. Её интерфейс:

  • Версия — свойство только для чтения;
  • Таймаут — свойство для чтения и записи, в секундах;
  • Обработать(Данные, ТекстОшибки) — функция, возвращает строку, ошибку пишет во второй параметр;
  • ЗапуститьНаблюдение(Каталог) — функция, возвращает Истина и начинает слать внешние события о новых файлах;
  • ОстановитьНаблюдение() — процедура.

Жизненный цикл компоненты:

  1. Хранение — ZIP со сборками и манифестом в макете конфигурации.
  2. Установка — один раз на клиентском компьютере, на сервере не нужна.
  3. Подключение — ПодключитьВнешнююКомпоненту или асинхронный аналог.
  4. Создание объекта — Новый("AddIn.Demo.Main").
  5. Работа — методы, свойства, внешние события.
  6. Освобождение — переменной присваивают Неопределено, а библиотека остаётся в памяти до завершения процесса.

Как устроена внешняя компонента 1С: Native API и COM

Native API — собственная технология 1С. Библиотека экспортирует несколько C-функций (GetClassNames, GetClassObject, DestroyObject), а её объекты реализуют интерфейс IComponentBase. В системе ничего не регистрируется: платформа берёт файл из макета и загружает сама. Поэтому одну компоненту собирают под Windows, Linux, macOS, мобильные ОС и браузеры.

COM досталась от 1С 7.7: DLL с интерфейсами IInitDone и ILanguageExtender. Она работает только в Windows, потому что COM — подсистема самой Windows: объект ищется по ProgID в реестре и создаётся системными библиотеками. В Linux, macOS и браузере этого механизма нет, поэтому COM не заработает на Linux-сервере, в веб-клиенте и на мобильной платформе.

ПризнакNative APICOM
ОС клиента и сервераWindows, Linux, macOSтолько Windows
Регистрация в системене нужнаregsvr32, реестр
Веб-клиентда, при сборке под браузернет
Новые разработкидатолько сопровождение старых

Технологию передают третьим параметром подключения: ТипВнешнейКомпоненты.Native или ТипВнешнейКомпоненты.COM. Указывайте её явно.

Где хранить компоненту: общий макет и ZIP с манифестом

Стандартное место — общий макет с типом «Внешняя компонента» (в старых конфигурациях — «Двоичные данные»). В него загружают ZIP-архив: в корне лежат библиотеки под каждую платформу и файл MANIFEST.XML, по которому платформа выбирает нужную сборку. Корневой элемент манифеста — bundle с пространством имён http://v8.1c.ru/8.2/addin/bundle, внутри по элементу на сборку: <component os="Windows" path="DemoWin64.dll" type="native" arch="x86_64"/>.

АтрибутЗначенияСмысл
osWindows, Linux, MacOSоперационная система
archi386, x86_64разрядность процесса 1С, а не ОС
typenativeтехнология
pathимя файлабиблиотека внутри архива

Сборки для веб-клиента описываются там же, с указанием браузера. Нет подходящей строки — подключение вернёт Ложь. Кроме общего макета, Местоположение принимает макет объекта ("Обработка.Загрузка.Макет.Компонента"), адрес во временном хранилище и путь к файлу (кроме веб-клиента).

Синхронное подключение и установка на клиенте

Самый короткий вариант. Работает в тонком и толстом клиенте, если в свойствах конфигурации «Режим использования синхронных вызовов расширений платформы и внешних компонент» не стоит «Не использовать».

// Общий модуль ДемоКомпонентаКлиент (флаг «Клиент (управляемое приложение)»).
// Синхронный вариант: режим использования синхронных вызовов расширений
// платформы и внешних компонент — «Использовать».

Функция Компонента() Экспорт

	ОбъектКомпоненты = ПараметрыПриложения.Получить("ДемоКомпонента.Объект");
	Если ОбъектКомпоненты <> Неопределено Тогда
		Возврат ОбъектКомпоненты; // уже создан в этом сеансе
	КонецЕсли;

	Местоположение = "ОбщийМакет.ДемоКомпонента";
	Подключена = ПодключитьВнешнююКомпоненту(Местоположение, "Demo", ТипВнешнейКомпоненты.Native);

	Если Не Подключена Тогда
		// Первый запуск на этом компьютере: диалог установки,
		// библиотека сохраняется в профиле пользователя
		УстановитьВнешнююКомпоненту(Местоположение);
		Подключена = ПодключитьВнешнююКомпоненту(Местоположение, "Demo", ТипВнешнейКомпоненты.Native);
	КонецЕсли;

	Если Не Подключена Тогда
		ВызватьИсключение НСтр("ru = 'Не удалось подключить внешнюю компоненту Demo на клиенте.'");
	КонецЕсли;

	ОбъектКомпоненты = Новый("AddIn.Demo.Main");
	ПараметрыПриложения.Вставить("ДемоКомпонента.Объект", ОбъектКомпоненты);

	Возврат ОбъектКомпоненты;

КонецФункции
  • ПараметрыПриложения — клиентское соответствие на весь сеанс: объект создаётся один раз и доступен из любой формы. В реквизит формы его не положить.
  • ПодключитьВнешнююКомпоненту возвращает Булево: если библиотеку загрузить не удалось, исключения не будет, поэтому результат проверяем явно.
  • УстановитьВнешнююКомпоненту срабатывает только при первом запуске на компьютере: платформа покажет диалог и сохранит библиотеку в профиле пользователя.
  • В "AddIn.Demo.Main" имя Demo задали мы при подключении, а Main объявила сама компонента.

Асинхронное подключение: НачатьПодключениеВнешнейКомпоненты и Асинх

В веб-клиенте и в конфигурациях на БСП, где синхронные вызовы запрещены, нужны асинхронные методы:

ДействиеСинхронноС оповещениемАсинх (8.3.18+)
Установка, только клиентУстановитьВнешнююКомпонентуНачатьУстановкуВнешнейКомпонентыУстановитьВнешнююКомпонентуАсинх
ПодключениеПодключитьВнешнююКомпонентуНачатьПодключениеВнешнейКомпонентыПодключитьВнешнююКомпонентуАсинх

Вариант на оповещениях работает и до 8.3.18:

// Тот же общий модуль ДемоКомпонентаКлиент. Вариант на оповещениях:
// работает в веб-клиенте и при запрете синхронных вызовов.
// Вызов из формы:
// ДемоКомпонентаКлиент.НачатьПолучениеКомпоненты(Новый ОписаниеОповещения("ПослеПолучения", ЭтотОбъект));
// В ПослеПолучения(ОбъектКомпоненты, ДополнительныеПараметры) придёт объект или Неопределено.

Процедура НачатьПолучениеКомпоненты(ОповещениеОЗавершении) Экспорт

	ОбъектКомпоненты = ПараметрыПриложения.Получить("ДемоКомпонента.Объект");
	Если ОбъектКомпоненты <> Неопределено Тогда
		ВыполнитьОбработкуОповещения(ОповещениеОЗавершении, ОбъектКомпоненты);
		Возврат;
	КонецЕсли;

	Контекст = Новый Структура;
	Контекст.Вставить("Местоположение", "ОбщийМакет.ДемоКомпонента");
	Контекст.Вставить("ОповещениеОЗавершении", ОповещениеОЗавершении);
	Контекст.Вставить("УстановкаБыла", Ложь);

	НачатьПодключениеДемо(Контекст);

КонецПроцедуры

Процедура НачатьПодключениеДемо(Контекст)

	Оповещение = Новый ОписаниеОповещения("ПослеПодключенияДемо", ДемоКомпонентаКлиент, Контекст);
	НачатьПодключениеВнешнейКомпоненты(Оповещение, Контекст.Местоположение, "Demo",
		ТипВнешнейКомпоненты.Native);

КонецПроцедуры

Процедура ПослеПодключенияДемо(Подключено, Контекст) Экспорт

	Если Подключено Тогда
		ОбъектКомпоненты = Новый("AddIn.Demo.Main");
		ПараметрыПриложения.Вставить("ДемоКомпонента.Объект", ОбъектКомпоненты);
		ВыполнитьОбработкуОповещения(Контекст.ОповещениеОЗавершении, ОбъектКомпоненты);

	ИначеЕсли Не Контекст.УстановкаБыла Тогда
		Контекст.УстановкаБыла = Истина;
		Оповещение = Новый ОписаниеОповещения("ПослеУстановкиДемо", ДемоКомпонентаКлиент, Контекст,
			"ПриОшибкеУстановкиДемо", ДемоКомпонентаКлиент);
		НачатьУстановкуВнешнейКомпоненты(Оповещение, Контекст.Местоположение);

	Иначе
		ВыполнитьОбработкуОповещения(Контекст.ОповещениеОЗавершении, Неопределено);
	КонецЕсли;

КонецПроцедуры

Процедура ПослеУстановкиДемо(Контекст) Экспорт

	НачатьПодключениеДемо(Контекст); // вторая попытка, уже после установки

КонецПроцедуры

Процедура ПриОшибкеУстановкиДемо(ИнформацияОбОшибке, СтандартнаяОбработка, Контекст) Экспорт

	СтандартнаяОбработка = Ложь; // сообщение покажет вызывающая форма
	ВыполнитьОбработкуОповещения(Контекст.ОповещениеОЗавершении, Неопределено);

КонецПроцедуры
  • В общем модуле нет ЭтотОбъект, поэтому в ОписаниеОповещения передаём сам модуль ДемоКомпонентаКлиент, а обработчики делаем экспортными.
  • Флаг УстановкаБыла не даёт зациклиться на «подключить — установить», если сборки под эту платформу в архиве нет.
  • Обработчик завершения установки получает только дополнительные параметры. Ошибку установки ловит отдельная процедура с параметрами ИнформацияОбОшибке и СтандартнаяОбработка.

С 8.3.18 тот же сценарий пишется линейно через Ждать. Метод компоненты в примере вызывается через НачатьВызов<ИмяМетода> — такой код работает и в веб-клиенте.

// Платформа 8.3.18 и выше. Общий модуль ДемоКомпонентаКлиент.

Асинх Функция КомпонентаАсинх() Экспорт

	ОбъектКомпоненты = ПараметрыПриложения.Получить("ДемоКомпонента.Объект");
	Если ОбъектКомпоненты <> Неопределено Тогда
		Возврат ОбъектКомпоненты;
	КонецЕсли;

	Местоположение = "ОбщийМакет.ДемоКомпонента";
	Подключена = Ждать ПодключитьВнешнююКомпонентуАсинх(Местоположение, "Demo", ТипВнешнейКомпоненты.Native);

	Если Не Подключена Тогда
		Попытка
			Ждать УстановитьВнешнююКомпонентуАсинх(Местоположение);
		Исключение
			Возврат Неопределено; // отказ от установки или нет сборки под эту платформу
		КонецПопытки;
		Подключена = Ждать ПодключитьВнешнююКомпонентуАсинх(Местоположение, "Demo", ТипВнешнейКомпоненты.Native);
	КонецЕсли;

	Если Подключена Тогда
		ОбъектКомпоненты = Новый("AddIn.Demo.Main");
		ПараметрыПриложения.Вставить("ДемоКомпонента.Объект", ОбъектКомпоненты);
	КонецЕсли;

	Возврат ОбъектКомпоненты; // объект или Неопределено

КонецФункции

// Модуль формы обработки с реквизитами ИсходныеДанные и Результат (Строка).

&НаКлиенте
Асинх Процедура КомандаОбработать(Команда)

	ОбъектКомпоненты = Ждать ДемоКомпонентаКлиент.КомпонентаАсинх();
	Если ОбъектКомпоненты = Неопределено Тогда
		ПоказатьПредупреждение(, НСтр("ru = 'Компонента Demo недоступна на этом рабочем месте.'"));
		Возврат;
	КонецЕсли;

	// Асинхронный вызов метода Обработать(Данные, ТекстОшибки)
	Оповещение = Новый ОписаниеОповещения("ПослеВызоваОбработать", ЭтотОбъект);
	ОбъектКомпоненты.НачатьВызовОбработать(Оповещение, Объект.ИсходныеДанные, "");

КонецПроцедуры

&НаКлиенте
Процедура ПослеВызоваОбработать(РезультатВызова, ПараметрыВызова, ДополнительныеПараметры) Экспорт

	ТекстОшибки = ПараметрыВызова[1]; // второй параметр компонента заполнила по ссылке
	Если ЗначениеЗаполнено(ТекстОшибки) Тогда
		ПоказатьПредупреждение(, ТекстОшибки);
		Возврат;
	КонецЕсли;

	Объект.Результат = РезультатВызова;

КонецПроцедуры
  • Асинх Функция возвращает Обещание, поэтому вызывающая процедура тоже объявлена Асинх и получает объект через Ждать.
  • Ошибка установки при Ждать становится исключением — отсюда Попытка вокруг УстановитьВнешнююКомпонентуАсинх.
  • НачатьВызовОбработать — асинхронная форма метода Обработать: префикс НачатьВызов плюс имя метода, первым параметром — оповещение. Для свойств есть НачатьПолучение<ИмяСвойства> и НачатьУстановку<ИмяСвойства>.
  • В ПараметрыВызова приходит массив параметров после вызова: так читаются значения, которые компонента вернула по ссылке.

В 8.3.27 анонсирован ещё и асинхронный конструктор объекта — СоздатьОбъектВнешнейКомпонентыАсинх.

Подключение на сервере и вызов методов

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

// Общий модуль ДемоКомпонентаВызовСервера (флаги «Сервер» и «Вызов сервера»).

Функция Обработать(ИсходныеДанные) Экспорт

	ОбъектКомпоненты = НовыйОбъектКомпоненты();
	ОбъектКомпоненты.Таймаут = 30;              // свойство для записи
	ВерсияКомпоненты = ОбъектКомпоненты.Версия; // свойство только для чтения

	ТекстОшибки = "";
	Попытка
		Результат = ОбъектКомпоненты.Обработать(ИсходныеДанные, ТекстОшибки);
	Исключение
		ЗаписьЖурналаРегистрации("ДемоКомпонента.Ошибка", УровеньЖурналаРегистрации.Ошибка, , ,
			ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		ВызватьИсключение;
	КонецПопытки;

	Если ЗначениеЗаполнено(ТекстОшибки) Тогда
		ВызватьИсключение СтрШаблон(НСтр("ru = 'Компонента Demo %1: %2'"), ВерсияКомпоненты, ТекстОшибки);
	КонецЕсли;

	Возврат Результат;

КонецФункции

Функция НовыйОбъектКомпоненты()

	// В процессе, где компонента уже загружена, повторное подключение проходит быстро
	Подключена = ПодключитьВнешнююКомпоненту("ОбщийМакет.ДемоКомпонента", "Demo", ТипВнешнейКомпоненты.Native);
	Если Не Подключена Тогда
		Информация = Новый СистемнаяИнформация;
		ВызватьИсключение СтрШаблон(
			НСтр("ru = 'Не удалось подключить внешнюю компоненту Demo на сервере (%1, платформа %2).'"),
			Информация.ТипПлатформы, Информация.ВерсияПриложения);
	КонецЕсли;

	Возврат Новый("AddIn.Demo.Main");

КонецФункции
  • Объект создаём в каждом серверном вызове: следующий может попасть в другой рабочий процесс.
  • Методы и свойства вызываются как у обычного объекта. Если компонента объявила русские и английские имена, работают оба.
  • ТекстОшибки передан по ссылке: компонента записывает в него текст, и переменная меняется.
  • Ошибку, о которой компонента сообщила платформе, 1С превращает в исключение: пишем его в журнал и пробрасываем дальше через ВызватьИсключение без параметров.
  • ТипПлатформы в тексте ошибки сразу показывает, какой сборки не хватает: Windows_x86_64, Linux_x86_64 и т. д.

У внешней обработки своих общих макетов нет, поэтому ZIP кладут в макет самой обработки и подключают через временное хранилище:

// Модуль объекта внешней обработки. ZIP компоненты лежит в её макете «Компонента»
// с типом «Двоичные данные».

Функция ОбработатьДанные(ИсходныеДанные) Экспорт

	Адрес = ПоместитьВоВременноеХранилище(ПолучитьМакет("Компонента"));
	Если Не ПодключитьВнешнююКомпоненту(Адрес, "DemoExt", ТипВнешнейКомпоненты.Native) Тогда
		ВызватьИсключение НСтр("ru = 'Не удалось подключить внешнюю компоненту из макета обработки.'");
	КонецЕсли;

	ОбъектКомпоненты = Новый("AddIn.DemoExt.Main");
	ТекстОшибки = "";
	Результат = ОбъектКомпоненты.Обработать(ИсходныеДанные, ТекстОшибки);
	Если ЗначениеЗаполнено(ТекстОшибки) Тогда
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;

	Возврат Результат;

КонецФункции

// Модуль формы этой обработки

&НаКлиенте
Процедура КомандаОбработать(Команда)

	ОбработатьНаСервере();

КонецПроцедуры

&НаСервере
Процедура ОбработатьНаСервере()

	Обработка = РеквизитФормыВЗначение("Объект");
	Объект.Результат = Обработка.ОбработатьДанные(Объект.ИсходныеДанные);

КонецПроцедуры
  • ПоместитьВоВременноеХранилище без идентификатора формы хранит данные до конца серверного вызова — подключению этого хватает.
  • Своё имя DemoExt не пересечётся с компонентами самой конфигурации.

Внешние события: ВнешнееСобытие и ОбработкаВнешнегоСобытия

Компонента сама сообщает 1С о происшествиях: вызывает ExternalEvent с тремя строками — источник, событие, данные. На клиенте их получают открытые формы с обработчиком ВнешнееСобытие и процедура ОбработкаВнешнегоСобытия модуля управляемого приложения. На сервере внешние события не обрабатываются.

// Модуль формы. Компонента шлёт ExternalEvent("DemoAddIn", "ФайлСоздан", <путь к файлу>).
// Обработчик ВнешнееСобытие назначьте в событиях формы. НовыеФайлы — реквизит формы
// (СписокЗначений), КаталогОбмена — реквизит обработки.

&НаКлиенте
Перем Наблюдатель;

&НаКлиенте
Процедура ВключитьНаблюдение(Команда)

	Наблюдатель = ДемоКомпонентаКлиент.Компонента(); // синхронный вариант из первого листинга
	Если Не Наблюдатель.ЗапуститьНаблюдение(Объект.КаталогОбмена) Тогда
		ВызватьИсключение НСтр("ru = 'Компонента не смогла начать наблюдение за каталогом.'");
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ВнешнееСобытие(Источник, Событие, Данные)

	// Источник — строка из ExternalEvent, а не имя "Demo" из ПодключитьВнешнююКомпоненту
	Если Источник <> "DemoAddIn" Тогда
		Возврат; // события других компонент не трогаем
	КонецЕсли;

	Если Событие = "ФайлСоздан" Тогда
		НовыеФайлы.Добавить(Данные);
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ПриЗакрытии(ЗавершениеРаботы)

	Если Наблюдатель <> Неопределено Тогда
		Наблюдатель.ОстановитьНаблюдение();
		Наблюдатель = Неопределено;
	КонецЕсли;

КонецПроцедуры

// Модуль управляемого приложения: событие приходит и при закрытых формах

Процедура ОбработкаВнешнегоСобытия(Источник, Событие, Данные)

	Если Источник = "DemoAddIn" И Событие = "Ошибка" Тогда
		ПоказатьОповещениеПользователя(НСтр("ru = 'Demo: ошибка наблюдения'"), , Данные);
	КонецЕсли;

КонецПроцедуры
  • Источник берите из описания компоненты: это её строка, а не символическое имя из подключения.
  • Событие получают все открытые формы с обработчиком, поэтому чужие источники, например оборудование, сразу пропускаем.
  • Модуль приложения получает события и при закрытых формах — здесь он показывает ошибки наблюдения.
  • Если события идут пачкой, а обработчик медленный, часть теряется: длину очереди задаёт сама компонента методом SetEventBufferDepth.

Типичные ошибки

  • «Не удалось подключить внешнюю компоненту…» Такой текст выводит БСП или ваш код, когда ПодключитьВнешнююКомпоненту вернула Ложь, — причину платформа не сообщает. Проверьте: есть ли в манифесте строка под ОС и разрядность процесса, установлена ли компонента на клиенте, хватает ли системных библиотек (Visual C++ Redistributable в Windows, вывод ldd в Linux).
  • Разрядность 32/64. 64-разрядный клиент или сервер не загрузит 32-разрядную библиотеку, и наоборот, поэтому в манифесте нужны сборки i386 и x86_64. COM-DLL тоже должна совпадать по разрядности с процессом 1С: 32-разрядную не увидит 64-разрядный rphost, даже если regsvr32 отработал без ошибок.
  • «Тип не определен (AddIn.Demo.Main)». Объект создают до успешного подключения, в другом контексте (подключили на сервере, создают на клиенте) или с опечаткой в имени.
  • «Метод объекта не обнаружен (Обработать)», «Поле объекта не обнаружено (Таймаут)». Такого имени нет в загруженной версии компоненты. «Поле объекта недоступно для записи (Версия)» — свойство только для чтения.
  • Нет прав. Служба 1С не может писать во временный каталог, на клиенте запрещена запись в профиль пользователя. Внешняя обработка или расширение в безопасном режиме не подключат компоненту без разрешения в профиле безопасности.
  • Linux-сервер. Временный каталог смонтирован с noexec — библиотека не загрузится. COM-компонента на Linux не работает вообще.
  • Веб-клиент. Синхронные методы не работают — нужны НачатьПодключениеВнешнейКомпоненты или Асинх-варианты и НачатьВызов…. В браузере должно стоять расширение для работы с 1С:Предприятием, а в манифесте — сборка под этот браузер.

Частые вопросы

Нужно ли устанавливать компоненту на сервере?

Нет: методы установки работают только на клиенте. Сервер распаковывает библиотеку из макета сам, нужна лишь сборка под его ОС и разрядность.

Можно ли подключить компоненту на сервере и пользоваться ею на клиенте?

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

Как загрузить внешнюю компоненту из файла?

Для отладки передайте в Местоположение полный путь к файлу на диске — макет не нужен, но в веб-клиенте так нельзя. Пользователям файл доставляют через макет, справочник или временное хранилище, как во внешней обработке выше.

Чем изолированный режим отличается от обычного?

С версии 8.3.21.1302 компоненту можно запустить в отдельном процессе: тип подключения задаёт необязательный параметр ПодключитьВнешнююКомпоненту. Если изолированная компонента упадёт, клиент или рабочий процесс сервера продолжат работу. Плата — межпроцессный обмен при каждом вызове; компонента должна поддерживать этот режим.

Когда проще заказать

Если компоненту нужно написать с нуля, собрать под Windows и Linux или встроить в типовую конфигурацию без синхронных вызовов, быстрее поручить это исполнителю — см. услуги по доработке 1С. Опишите библиотеку, версию платформы и клиенты на странице «Разместить задание», и исполнители оценят сроки и стоимость.

По теме

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.


1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.