При переходе на современные интерфейсы (Такси) и работу через веб-клиенты программисты часто сталкиваются с тем, что старые проверенные методы работы с файловой системой перестают функционировать. В этой статье мы подробно разберем, как эволюционировали механизмы манипуляции файлами в 1С 8.3, почему привычный Scripting.FileSystemObject больше не подходит и как реализовать копирование без лишних диалоговых окон.
Ранее для копирования файлов часто использовался COM-объект Scripting.FileSystemObject. Рассмотрим типичный пример такого кода:
FSO = Новый COMОбъект("Scripting.FileSystemObject");
FSO.CopyFile(ИмяФайлаИсточник, ИмяФайлаНазначение, -1);
FSO = Неопределено;
Этот подход отлично работает в толстом клиенте под Windows, но абсолютно бесполезен в веб-клиенте (браузере) или при работе на Linux. Браузеры (Chrome, Firefox, Safari) из соображений безопасности не позволяют веб-приложениям напрямую обращаться к COM-объектам операционной системы. Более того, современные браузеры блокируют любые синхронные вызовы, которые приостанавливают поток выполнения кода. Именно поэтому при попытке выполнить проверку файла в Chrome вы можете увидеть ошибку: «Использование синхронных методов на клиенте запрещено».
Если ваша задача ограничена работой в тонком клиенте, можно использовать встроенную функцию глобального контекста КопироватьФайл(). Проанализируем её синтаксис:
КопироватьФайл("C:\Temp\Source.txt", "D:\Backup\Target.txt");
Этот метод прост, но имеет существенные ограничения в веб-клиенте. Во-первых, для его работы в браузере обязательно должно быть установлено и подключено расширение работы с файлами. Во-вторых, даже с расширением, вызов этого метода может считаться синхронным, что приведет к ошибке в современных версиях платформы 1С при работе в браузере.
Для работы в режиме «Такси» и обеспечения совместимости со всеми браузерами необходимо использовать асинхронную модель. Рассмотрим, как это реализовать. Основная идея заключается в использовании объекта ОписаниеОповещения, который указывает системе, какую процедуру нужно выполнить после того, как операция копирования будет завершена.
Разберем алгоритм по шагам:
НачатьКопированиеФайла(), передавая в него пути к файлам.Посмотрим на пример кода:
&НаКлиенте
Процедура ВыполнитьКопирование()
Оповещение = Новый ОписаниеОповещения("ЗавершитьКопирование", ЭтотОбъект);
ИмяФайлаИсточник = "C:\Data\Report.pdf";
ИмяФайлаНазначение = "D:\Archive\Report_Copy.pdf";
// Метод не блокирует интерфейс и работает в веб-клиенте
НачатьКопированиеФайла(Оповещение, ИмяФайлаИсточник, ИмяФайлаНазначение);
КонецПроцедуры
&НаКлиенте
Процедура ЗавершитьКопирование(ДополнительныеПараметры) Экспорт
Сообщить("Файл успешно скопирован!");
КонецПроцедуры
Перед копированием часто требуется проверить, существует ли уже файл по целевому пути. Синхронный метод Файл.Существует() в веб-клиенте вызовет ту же ошибку блокировки. Проанализируем ситуацию и применим асинхронный подход с использованием НачатьПроверкуСуществования():
&НаКлиенте
Процедура ПроверитьИСкопировать()
ФайлПроверки = Новый Файл("D:\Target.txt");
Оповещение = Новый ОписаниеОповещения("ПослеПроверкиСуществования", ЭтотОбъект);
ФайлПроверки.НачатьПроверкуСуществования(Оповещение);
КонецПроцедуры
&НаКлиенте
Процедура ПослеПроверкиСуществования(Существует, ДополнительныеПараметры) Экспорт
Если Существует Тогда
Сообщить("Файл уже есть на диске, копирование отменено.");
Иначе
// Здесь можно вызывать НачатьКопированиеФайла
КонецЕсли;
КонецПроцедуры
Многие пользователи жалуются, что при вызове файловых методов браузер или 1С выдают запрос: «Разрешить расширению 1С манипуляции с файлами?» или «Скопировать файл?». Выясним причину:
1. Безопасность браузера: Полностью программно отключить первый запрос «Разрешить доступ к файловой системе» невозможно. Это защита на уровне Chrome/Firefox. Однако, если пользователь один раз нажмет «Больше не спрашивать», браузер запомнит это решение для данного адреса базы.
2. Явное указание путей: Если вы используете диалоги выбора файлов (НачатьПомещениеФайла), интерактивность неизбежна. Но если вы используете НачатьКопированиеФайла с заранее определенными строковыми путями, система не будет открывать окно выбора проводника.
Если вам нужно скопировать файл между сетевыми папками или внутри сервера, лучшим решением будет уйти от клиентских методов вообще. На сервере 1С нет ограничений браузера, нет нужды в расширениях работы с файлами и нет асинхронных сложностей. Рассмотрим схему:
ПоместитьФайлНаСервер().КопироватьФайл().Проанализируем пример серверного кода, где пути доступны серверу:
&НаСервере
Процедура КопироватьНаСервере(Путь1, Путь2)
// Серверу не нужны расширения и оповещения
Попытка
КопироватьФайл(Путь1, Путь2);
Исключение
ЗаписьЖурналаРегистрации("Ошибка копирования", УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецПроцедуры
Для того чтобы клиентские методы (синхронные или асинхронные) работали в браузере, необходимо убедиться, что расширение подключено. Рекомендуем использовать следующий блок кода при начале работы системы или перед файловыми операциями:
&НаКлиенте
Асинхронная Процедура ПодключитьФайлы()
Если Не РасширениеРаботыСФайламиПодключено() Тогда
Ждать НачатьПодключениеРасширенияРаботыСФайлами();
КонецЕсли;
КонецПроцедуры
Использование ключевого слова Ждать (доступно в новых версиях платформы) позволяет писать асинхронный код в линейном стиле, что значительно упрощает чтение и отладку программы.
Подведем итог: для стабильной работы в 1С 8.3 (Такси) забудьте про COM-объекты. Используйте асинхронные методы НачатьКопированиеФайла на клиенте или переносите тяжелую логику на сервер, где можно использовать простые синхронные команды. Это обеспечит кроссплатформенность и стабильную работу вашего приложения во всех популярных браузерах.