В процессе разработки и внедрения прикладных решений на платформе 1С:Предприятие часто возникает задача интеграции с внешним программным обеспечением. Это может быть запуск специализированного терминала, запуск утилит вроде Far Manager, открытие локальных файлов в сторонних редакторах или передача параметров во внешние исполняемые файлы (.exe). Когда пользователи работают через Тонкий или Толстый клиент, запуск внешних приложений не вызывает трудностей. Однако при переходе на веб-клиент разработчики сталкиваются с тем, что код, успешно работающий на локальном компьютере разработчика, напрочь отказывается функционировать у удаленных пользователей, выдавая ошибку подключения расширения.
В этой статье мы подробно разберем, почему возникает эта проблема, как устроены механизмы безопасности современных браузеров, и пошагово реализуем правильное подключение расширения работы с файлами для запуска внешних программ как старым способом (через механизмы обратного вызова), так и с использованием современных асинхронных методов платформы 1С.
Для начала проанализируем ситуацию и разберемся в архитектуре выполнения кода. Браузер (будь то Google Chrome, Mozilla Firefox, Microsoft Edge или Safari) по умолчанию работает в изолированной среде — так называемой «песочнице» (sandbox). Это фундаментальный стандарт безопасности в Интернете. Если бы любой веб-сайт мог беспрепятственно запускать исполняемые файлы на компьютере пользователя, это привело бы к моментальному заражению миллионов компьютеров вредоносным ПО.
Когда мы запускаем веб-клиент 1С, вся логика клиентских процедур выполняется движком JavaScript самого браузера. Соответственно, стандартный метод ЗапуститьПриложение() напрямую из веб-клиента выполнен быть не может. Чтобы обойти это ограничение и дать возможность бизнес-приложениям безопасно взаимодействовать с операционной системой, фирма 1С разработала технологию Расширения работы с файлами.
Данная технология базируется на механизме Native Messaging (обмен сообщениями с нативными приложениями):
Почему код работает на компьютере разработчика, но не работает у удаленного клиента? На компьютере разработчика установлена полная версия платформы 1С и веб-сервер (например, Apache). В процессе установки платформы в операционной системе автоматически зарегистрировались все необходимые компоненты и ключи реестра для взаимодействия с браузером. У удаленного же пользователя в системе нет этого локального посредника, даже если он установил расширение в сам браузер из магазина приложений Firefox или Chrome. Браузер пытается связаться с локальной частью 1С, не находит ее в реестре и возвращает ошибку подключения.
Чтобы запуск внешних приложений через веб-клиент стал возможен на удаленном компьютере, необходимо выполнить предварительную настройку операционной системы и браузера пользователя:
HKEY_CURRENT_USER\SOFTWARE\Google\Chrome\NativeMessagingHosts\ (или аналогичные для других браузеров), указывающие на исполняемый файл связи 1С с браузером.Рассмотрим, как правильно написать код инициализации расширения и запуска приложения, используя асинхронную модель с обратными вызовами (колбэками). Этот метод актуален для конфигураций, работающих на более старых версиях платформы 1С:Предприятие 8.3.
Для запуска приложения (в нашем примере это Far Manager, расположенный по стандартному пути) нам понадобятся три процедуры на клиенте:
&НаКлиенте
Процедура ЗапуститьВнешнееПриложение(Команда)
// Шаг 1: Инициализируем подключение расширения работы с файлами.
// Передаем описание оповещения, которое сработает после попытки подключения.
Оповещение = Новый ОписаниеОповещения("ПослеПодключенияРасширения", ЭтаФорма);
НачатьПодключениеРасширенияРаботыСФайлами(Оповещение);
КонецПроцедуры
&НаКлиенте
Процедура ПослеПодключенияРасширения(Подключено, ДополнительныеПараметры) Экспорт
// Шаг 2: Анализируем результат подключения расширения.
Если Подключено Тогда
// Задаем параметры запуска приложения.
// Первый параметр - путь к исполняемому файлу.
// Второй параметр - рабочая директория (каталог запуска).
ПутьКФайлу = "C:\Program Files\Far Manager\Far.exe";
РабочийКаталог = "C:\Program Files\Far Manager\";
ОповещениеЗапуска = Новый ОписаниеОповещения("ПослеЗапускаПриложения", ЭтаФорма);
// Вызываем асинхронный запуск
НачатьЗапускПриложения(ОповещениеЗапуска, ПутьКФайлу, РабочийКаталог);
Иначе
// Если расширение не подключено, предлагаем пользователю установить его
ПоказатьПредупреждение(, "Не удалось подключить расширение работы с файлами.
|Убедитесь, что расширение 1С установлено в браузере и на компьютере установлена локальная платформа.");
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПослеЗапускаПриложения(КодВозврата, ДополнительныеПараметры) Экспорт
// Шаг 3: Обрабатываем успешный запуск или анализируем код возврата.
Если КодВозврата = Неопределено Тогда
// В веб-клиенте код возврата может не возвращаться напрямую,
// но отсутствие критической ошибки говорит о том, что команда отправлена операционной системе.
Сообщить("Команда на запуск приложения успешно отправлена.");
Иначе
Сообщить("Приложение завершило работу с кодом: " + КодВозврата);
КонецЕсли;
КонецПроцедуры
В данном коде процедура НачатьПодключениеРасширенияРаботыСФайлами проверяет наличие установленного плагина и локального хоста. Если все требования соблюдены, управление передается в процедуру ПослеПодключенияРасширения с параметром Подключено = Истина, после чего отрабатывает метод НачатьЗапускПриложения.
В современных версиях платформы 1С:Предприятие (начиная с релиза 8.3.18) разработчикам доступен гораздо более удобный, лаконичный и читаемый асинхронный код, использующий конструкцию Асинх и оператор Ждать. Это позволяет отказаться от создания множества вспомогательных процедур-оповещений и писать линейный код.
Рассмотрим, как будет выглядеть современная реализация этой же задачи:
&НаКлиенте
Асинх Процедура ЗапуститьВнешнееПриложениеСовременныйМетод(Команда)
#Если ВебКлиент Тогда
// Шаг 1: Асинхронно проверяем и подключаем расширение
Подключено = Ждать ПодключитьРасширениеРаботыСФайламиАсинх();
Если Не Подключено Тогда
// Если расширение не установлено, предлагаем установить его в интерактивном режиме
Попытка
Ждать УстановитьРасширениеРаботыСФайламиАсинх();
// Повторяем попытку подключения после установки
Подключено = Ждать ПодключитьРасширениеРаботыСФайламиАсинх();
Исключение
ЗаписьЖурналаРегистрации("Интеграция", УровеньЖурналаРегистрации.Ошибка,,,
ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
#Иначе
// В Тонком и Толстом клиентах расширение работы с файлами всегда доступно по умолчанию
Подключено = Истина;
#КонецЕсли;
// Шаг 2: Если расширение успешно подключено, выполняем запуск приложения
Если Подключено Тогда
ПутьКПриложению = "C:\Program Files\Far Manager\Far.exe";
ПараметрыЗапуска = ""; // Здесь можно указать ключи запуска, например, пути к каталогам
Попытка
// Запуск приложения в асинхронном режиме без блокировки интерфейса 1С
Ждать ЗапуститьПриложениеАсинх(ПутьКПриложению, ПараметрыЗапуска);
ПоказатьОповещениеПользователя("Успешно",, "Приложение запущено", БиблиотекаКартинок.Информация);
Исключение ОписаниеОшибки
Предупреждение("Не удалось запустить приложение. Ошибка: " + КраткоеПредставлениеОшибки(ОписаниеОшибки));
КонецПопытки;
Иначе
ПоказатьПредупреждение(, "Не удалось подключить интеграцию с операционной системой!");
КонецЕсли;
КонецПроцедуры
Использование конструкции Ждать ПодключитьРасширениеРаботыСФайламиАсинх() делает код чистым, избавляет от «ада колбэков» (callback hell) и значительно упрощает отладку взаимодействия веб-клиента с локальной файловой системой.
Реализуя запуск внешних приложений на компьютерах пользователей через веб-браузер, необходимо помнить о правилах безопасности программирования в среде 1С:
ЗапуститьПриложениеАсинх() строки, сформированные напрямую из пользовательского ввода или ненадёжных источников в базе данных без предварительной проверки. Злоумышленник может внедрить в строку запуска спецсимволы терминала (например, символы конвейера команд &, |, ; в Windows) и выполнить несанкционированные действия в операционной системе от имени текущего пользователя.