При разработке внешних отчетов и обработок в среде «1С:Предприятие 8.3» программисты часто сталкиваются с неприятной ситуацией. Внешняя обработка, которая отлично работала в процессе отладки, при интерактивном открытии обычным пользователем через меню Файл -> Открыть внезапно аварийно завершается. На экран выводится системное сообщение: «Установлен безопасный режим. Выполнение операции запрещено».
Особенно сильное недоумение это вызывает тогда, когда в коде используются исключительно временные файлы. Ведь, согласно официальной документации платформы 1С, работа с временной файловой системой в безопасном режиме разрешена. Давайте подробно проанализируем причины этого поведения платформы и разберем по шагам все возможные способы решения данной проблемы.
Для начала рассмотрим классический код, который приводит к возникновению этой ошибки:
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВХ);
ИВФ = ПолучитьИмяВременногоФайла(Расширение);
Попытка
ДвоичныеДанные.Записать(ИВФ); // Здесь происходит падение
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
ТД = Новый ТабличныйДокумент;
ТД.Прочитать(ИВФ);
Почему же падает метод Записать() объекта ДвоичныеДанные, хотя мы пишем файл во временный каталог, путь к которому получили легальным методом ПолучитьИмяВременногоФайла()? Дело в архитектурных особенностях системы безопасности 1С:
ДвоичныеДанные.Записать(), ТабличныйДокумент.Прочитать(), ТабличныйДокумент.Записать(), а также конструктор Новый ДвоичныеДанные(ИмяФайла), входят в список безусловно запрещенных в безопасном режиме. Платформа 1С не проверяет динамически, ведет ли переданный в метод путь в разрешенную папку Temp. Она просто блокирует выполнение самого метода на системном уровне.УстановитьБезопасныйРежим(Ложь) внутри самого кода обработки невозможно.Ниже мы подробно разберем несколько практических способов обхода и решения этой проблемы.
Это самый быстрый и прямолинейный способ, который часто применяется на практике, когда обработку не нужно запускать в облачных сервисах (например, в «1С:Fresh»). Мы можем сделать обработку подключаемой к Библиотеке Стандартных Подсистем (БСП) и явно указать системе, что ее нужно запускать без ограничений безопасного режима.
Для этого в модуле объекта нашей внешней обработки необходимо прописать стандартизированную экспортную функцию СведенияОВнешнейОбработке() следующим образом:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
ПараметрыРегистрации.Информация = "Обработка импорта данных из файла Excel";
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиДополнительнаяОбработка();
ПараметрыРегистрации.Версия = "1.0";
// Ключевой параметр: принудительно отключаем безопасный режим
ПараметрыРегистрации.Вставить("БезопасныйРежим", Ложь);
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = "Запустить импорт данных";
НоваяКоманда.Идентификатор = "ЗапускИмпорта";
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипЗапускаВызовСерверногоМетода();
НоваяКоманда.ПоказыватьОповещение = Истина;
Возврат ПараметрыРегистрации;
КонецФункции
После этого вам нужно зайти в информационную базу под учетной записью администратора, перейти в справочник Дополнительные отчеты и обработки, загрузить туда вашу обработку и сохранить ее. Теперь при запуске этой обработки из интерфейса программы никаких ошибок возникать не будет, так как платформа отключит безопасный режим для этого кода.
Если ваша информационная база работает в жестком контуре безопасности или развернута в облаке, полное отключение безопасного режима ("БезопасныйРежим", Ложь) будет заблокировано администратором или аудитом кода. В этом случае правильным решением будет запуск обработки в безопасном режиме, но с запросом конкретных точечных разрешений на доступ к временным файлам.
Давайте посмотрим, как модифицировать функцию СведенияОВнешнейОбработке(), чтобы запросить доступ у системы:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиДополнительнаяОбработка();
ПараметрыРегистрации.Версия = "1.0";
// Оставляем безопасный режим включенным
ПараметрыРегистрации.Вставить("БезопасныйРежим", Истина);
// Запрашиваем разрешение на работу с временными файлами
Разрешения = Новый Массив;
// Разрешаем чтение и запись в каталог временных файлов
РазрешениеФайлы = РаботаВБезопасномРежиме.РазрешениеНаИспользованиеКаталогаВременныхФайлов(Истина, Истина);
Разрешения.Добавить(РазрешениеФайлы);
ПараметрыРегистрации.Вставить("Разрешения", Разрешения);
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = "Запустить импорт данных";
НоваяКоманда.Идентификатор = "ЗапускИмпорта";
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипЗапускаВызовСерверногоМетода();
Возврат ПараметрыРегистрации;
КонецФункции
Когда администратор будет регистрировать такую обработку в справочнике дополнительных обработок, система автоматически отобразит окно с запросом разрешений. Администратор нажмет кнопку «Разрешить выполнение операций», и платформа сделает исключение для нашей обработки: операции записи и чтения временных файлов встроенными методами пройдут успешно.
Начиная с версии платформы 1С 8.3.9, у разработчиков появилась возможность работать с потоками в оперативной памяти с помощью объекта ПотокВПамяти. Этот подход позволяет полностью отказаться от записи временных файлов на жесткий диск сервера, тем самым обходя любые ограничения безопасного режима.
Однако здесь есть важное ограничение платформы: объект ТабличныйДокумент не умеет читать форматы XLS и XLSX напрямую из потока. Из потоков поддерживаются исключительно форматы MXL (родной формат 1С) и ODS (OpenDocument Spreadsheet). Рассмотрим, как обойти это ограничение:
// Получаем двоичные данные файла MXL из хранилища
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВХ);
// Инициализируем поток в оперативной памяти на основе двоичных данных
Поток = Новый ПотокВПамяти(ДвоичныеДанные);
// Считываем табличный документ из потока
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(Поток, СпособЧтенияТабличногоДокумента.MXL);
Поток.Закрыть();
// Дальнейшая обработка табличного документа в памяти
Для сложных ситуаций с парсингом тяжелых файлов Excel в облачных средах часто используют сторонние библиотеки на чистом коде 1С. Поскольку формат XLSX является обычным ZIP-архивом, внутри которого лежат XML-схемы, программисты распаковывают архив в памяти с помощью объектов ЧтениеZIPФайла и разбирают его через ЧтениеXML без единого обращения к файловой системе сервера.
Если вы являетесь администратором системы, и вам нужно разрешить пользователям запуск любых локальных обработок без переписывания их кода под требования БСП, вы можете настроить профили безопасности непосредственно на уровне кластера серверов «1С:Предприятие».
Для реализации этого метода выполните следующие шаги:
DefaultSafeModeProfile).После применения этих настроек все внешние обработки, запускаемые интерактивно, будут наследоваться от созданного вами профиля кластера и получат легальный доступ к дисковым операциям временных файлов.
Этот способ подходит исключительно для локальных баз разработчиков, учебных баз или тестовых контуров, где вопросы безопасности не стоят остро, и нужно избавиться от назойливых предупреждений системы.
Чтобы полностью отключить контроль безопасного режима платформой, выполните следующие действия:
ИспользуютсяПрофилиБезопасности).Ложь) и сохраните изменения.После этого платформа перестанет жестко контролировать запуск обработок через меню Файл -> Открыть, и ошибка безопасного режима пропадет навсегда.