Как отключить безопасный режим во внешней обработке 1С и исправить ошибку выполнения операции

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

При разработке и сопровождении конфигураций на платформе 1С:Предприятие разработчики часто сталкиваются с ситуацией: внешняя обработка успешно читает данные, но при попытке записать файл на диск сервера, запустить системную команду или обратиться к COM-объекту падает с критической ошибкой «Установлен безопасный режим. Выполнение операции запрещено».

Первая интуитивная попытка исправить ситуацию — написать в коде самой обработки конструкцию:


Если БезопасныйРежим() Тогда
    УстановитьБезопасныйРежим(Ложь);
КонецЕсли;

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

Почему возникает ошибка при попытке отключить безопасный режим кодом

Проанализируем механику работы метода УстановитьБезопасныйРежим(). В платформе 1С этот механизм функционирует по принципу парного стека вызовов в пределах одного контекста (конкретной процедуры или функции):

  1. Защита от взлома изнутри: если бы изолированный программный код мог самостоятельно отключить наложенные на него ограничения, концепция безопасного режима теряла бы смысл. Вредоносный код во внешней обработке мог бы первой строкой снять защиту и получить доступ к файловой системе операционной системы.
  2. Стековая модель вызовов: метод УстановитьБезопасныйРежим(Ложь) может быть вызван исключительно в том случае, если ранее в этой же самой процедуре или функции был выполнен вызов УстановитьБезопасныйРежим(Истина). Если количество вызовов с параметром Ложь превышает количество предшествующих вызовов с параметром Истина в текущем контексте, платформа немедленно генерирует исключение.

Посмотрим на пример правильного локального использования безопасного режима внутри кода конфигурации:


Процедура ВыполнитьНедоверенныйАлгоритм()
    // Включаем безопасный режим перед выполнением опасного участка
    УстановитьБезопасныйРежим(Истина);
    
    Попытка
        // Выполнение потенциально небезопасного кода
        Выполнить(НекийВнешнийТекст);
    Исключение
        // Обязательно возвращаем исходное состояние в случае ошибки
        УстановитьБезопасныйРежим(Ложь);
        ВызватьИсключение;
    КонецПопытки;
    
    // Выключаем безопасный режим в той же процедуре
    УстановитьБезопасныйРежим(Ложь);
КонецПроцедуры

Если внешняя обработка уже была запущена в безопасном режиме, вызов функции БезопасныйРежим() вернет Истина, однако снять этот флаг изнутри модуля обработки невозможно, так как он был установлен внешним контекстом.

Что запрещено выполнять в безопасном режиме

Выясним, какие именно операции блокируются платформой при активном безопасном режиме:

  1. Любые операции с файловой системой на стороне сервера: создание, изменение и удаление файлов и каталогов. Именно поэтому попытка вызова метода ДвоичныеДанные.Записать(ПутьНаСервере) завершается аварийно.
  2. Использование привилегированного режима: вызовы УстановитьПривилегированныйРежим(Истина) полностью игнорируются либо вызывают исключительную ситуацию.
  3. Запуск внешних исполняемых файлов: блокируются функции ЗапуститьПриложение() и КомандаСистемы().
  4. Работа с внешними компонентами и объектами операционной системы: создание объектов через Новый COMОбъект(...) и загрузка сторонних библиотек.
  5. Непосредственный доступ к внешним источникам данных: ограничивается прямое обращение к базам через сторонние драйверы.

Причины автоматического включения безопасного режима

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

  1. Интерактивное открытие файла пользователем без административных прав: если у пользователя в системе нет роли с правом «Администрирование» (или «Полные права»), при интерактивном открытии любого внешнего отчета или обработки через пункт меню Файл — Открыть платформа 1С автоматически изолирует исполняемый код и принудительно активирует безопасный режим.
  2. Программное создание внешней обработки без указания параметров: при вызове методов ВнешниеОбработки.Создать() или ВнешниеОбработки.Подключить() параметр безопасного режима по умолчанию часто принимает значение Истина.
  3. Использование подсистемы «Дополнительные отчеты и обработки» (БСП): при регистрации дополнительных обработок флаг безопасного режима может быть принудительно выставлен в настройках справочника администратором.

Варианты решения проблемы

Рассмотрим по шагам практические способы решения проблемы в зависимости от архитектуры вашей базы данных.

Способ 1. Корректное программное подключение внешней обработки

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

Разберем пример создания объекта из файла на диске:


// Второй параметр метода Создать() определяет признак безопасного режима
ПутьКОбработке = "C:\Обработки\ЗагрузкаДанных.epf";
ОбработкаОбъект = ВнешниеОбработки.Создать(ПутьКОбработке, Ложь);
ОбработкаОбъект.ВыполнитьЗагрузку();

Посмотрим на пример подключения обработки из временного хранилища на сервере:


// Третий параметр метода Подключить() отвечает за безопасный режим
ИмяОбработки = ВнешниеОбработки.Подключить(АдресВоВременномХранилище, , Ложь);
ОбработкаОбъект = ВнешниеОбработки.Создать(ИмяОбработки, Ложь);
ОбработкаОбъект.ЗапуститьОбработку();

Способ 2. Вынос файловых операций в серверный общий модуль конфигурации

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

Разберем реализацию по шагам:

  1. В конфигураторе создадим или откроем существующий общий модуль (например, ФайловыеОперацииСервер).
  2. Убедимся, что у модуля установлены флаги Сервер и Вызов сервера. Если требуется обход прав доступа, включим флаг Привилегированный.
  3. Создадим экспортную процедуру для сохранения файла:

// Процедура в общем модуле ФайловыеОперацииСервер
Процедура СохранитьФайлНаСервере(ДвоичныеДанные, ПутьНаСервере) Экспорт
    ДвоичныеДанные.Записать(ПутьНаСервере);
КонецПроцедуры
  1. В модуле внешней обработки заменим прямую запись на вызов процедуры общего модуля:

// Код внутри внешней обработки
ПутьНаСервере = КаталогВременныхФайлов() + "loaddetali.xml";
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВременногоХранилища);

// Вызываем процедуру общего модуля конфигурации вместо прямой записи
ФайловыеОперацииСервер.СохранитьФайлНаСервере(ДвоичныеДанные, ПутьНаСервере);

Код общих модулей конфигурации выполняется в доверенном контексте и не наследует ограничения безопасного режима внешней обработки.

Способ 3. Регистрация в подсистеме БСП «Дополнительные отчеты и обработки»

Если конфигурация разработана с использованием Библиотеки Стандартных Подсистем (БСП), внешняя обработка должна содержать экспортную функцию СведенияОВнешнейОбработке() в модуле объекта.

Посмотрим на пример структуры описания обработки с отключением безопасного режима:


Функция СведенияОВнешнейОбработке() Экспорт
    ПараметрыРегистрации = Новый Структура;
    ПараметрыРегистрации.Вставить("Вид", "ДополнительнаяОбработка");
    ПараметрыРегистрации.Вставить("Наименование", "Загрузка деталей");
    ПараметрыРегистрации.Вставить("Версия", "1.0");
    ПараметрыРегистрации.Вставить("БезопасныйРежим", Ложь);
    ПараметрыРегистрации.Вставить("Информация", "Обработка загрузки файлов XML");
    
    ТаблицаКоманд = Новый ТаблицаЗначений;
    ТаблицаКоманд.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
    ТаблицаКоманд.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));
    ТаблицаКоманд.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
    
    НоваяКоманда = ТаблицаКоманд.Добавить();
    НоваяКоманда.Идентификатор = "ЗагрузитьДанные";
    НоваяКоманда.Использование = "ВызовСерверногоМетода";
    НоваяКоманда.Представление = "Загрузить данные из XML";
    
    ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
    Возврат ПараметрыРегистрации;
КонецФункции

Важно: если обработка уже была ранее загружена в справочник «Дополнительные отчеты и обработки», изменение кода функции СведенияОВнешнейОбработке() не отключит безопасный режим автоматически. Администратору необходимо зайти в элемент справочника и вручную снять флаг Безопасный режим в карточке обработки.

Различие между «Безопасным режимом» и «Защитой от опасных действий»

При настройке прав часто путают два независимых механизма платформы:

  1. Безопасный режим (Safe Mode): системное ограничение прав кода на доступ к файлам, внешним компонентам и вызовам команд ОС. Регулируется правами пользователя и параметрами запуска обработки.
  2. Защита от опасных действий: предупреждающее диалоговое окно платформы (начиная с версии 8.3.9), запрашивающее у пользователя подтверждение на открытие внешнего файла или запуск программы. Снятие флага защиты в карточке пользователя отключает лишь предупреждения, но не снимает системных ограничений безопасного режима на запись файлов.

Таким образом, для устранения ошибки записи файлов на сервере необходимо либо передавать Ложь при программном создании объекта ВнешняяОбработка, либо выносить файловые операции в доверенные серверные модули конфигурации.

← На главную