При разработке интеграций часто возникает ситуация, когда код, успешно работающий в обычной обработке или консоли запросов, начинает вести себя некорректно при вызове через Веб-сервис. Одной из самых распространенных проблем является "исчезновение" файлов: функция НайтиФайлы возвращает пустой массив или 0 объектов, хотя файлы гарантированно находятся в папке. Давайте подробно разберем, почему это происходит, и как правильно настроить окружение для корректной работы с файловой системой.
Первое, что нам необходимо проанализировать — это контекст выполнения кода. Когда вы запускаете поиск файлов из обработки под своим пользователем, код выполняется в контексте вашего сеанса. Он видит все диски (включая сетевые Z:\, X:\) и имеет те же права на папки, что и ваш пользователь в Windows.
Однако, как только вызов идет через веб-сервис, ситуация кардинально меняется. Рассмотрим основные отличия:
D:\ТестоваяПапка будет искаться на той физической машине, где установлен веб-сервер (IIS или Apache), а не на компьютере пользователя.IUSR, NetworkService или ApplicationPoolIdentity в IIS). У этой записи по умолчанию крайне ограниченные права в операционной системе.Проанализируем пример кода, который часто вызывает затруднения:
Функция ПолучитьФайлыИзПапки(ПутьПоиска) Экспорт
// Если ПутьПоиска = "D:\Files", сервер будет искать их у себя локально
ИскомыеФайлы = НайтиФайлы(ПутьПоиска, "*.dbf");
Возврат ИскомыеФайлы.Количество();
КонецФункции
Если веб-сервер и сервер 1С находятся на разных машинах, этот код гарантированно не найдет файлы, так как обращается к локальному диску "своей" машины.
Для того чтобы файлы были доступны из любого контекста, мы должны отказаться от использования букв дисков (C:\, D:\) в пользу сетевых путей формата UNC (Universal Naming Convention). Рассмотрим, как это выглядит на практике.
Вместо локального пути используем сетевое имя сервера:
\\ИмяСервера\ИмяРесурса\Папка\
Важно помнить, что сетевые диски, подключенные в вашей сессии Windows (например, диск Z:, указывающий на \\Server\Share), абсолютно невидимы для служб веб-сервера. Службы работают в так называемой "нулевой сессии", где нет никаких подключенных пользовательских дисков. Поэтому всегда прописывайте полный сетевой путь в коде или константах конфигурации.
Даже если путь указан верно, функция НайтиФайлы вернет пустое значение, если у пользователя, от имени которого запущен веб-сервер, нет прав на чтение папки. Выясним, как это исправить по шагам:
IIS_IUSRS или конкретную доменную учетную запись).НайтиФайлы необходимы права "Чтение" и "Список содержимого папки".Внимание: Если 1С-сервер и файлы находятся на разных машинах, "локальных" пользователей веб-сервера (типа IUSR) будет недостаточно. В этом случае необходимо запускать пул приложений IIS и службу "Агент сервера 1С:Предприятия" от имени доменной учетной записи, которая имеет доступ к сетевому хранилищу.
Если вы хотите избежать сложностей с настройкой прав доступа к файловой системе на сервере, рассмотрим более современный и безопасный архитектурный подход. Вместо того чтобы заставлять веб-сервис "ходить" за файлами, мы можем передавать содержимое файла напрямую в параметрах запроса.
Посмотрим на пример реализации передачи файла в веб-сервис:
// Код на стороне отправителя (клиента)
ПутьКФайлу = "D:\Data.dbf";
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлу);
// Передаем эти данные в веб-сервис как параметр типа base64Binary
Прокси.ЗагрузитьФайл(ДвоичныеДанныеФайла);
// Код на стороне веб-сервиса (сервера)
Функция ЗагрузитьФайл(ДанныеФайла)
// Здесь ДанныеФайла уже имеют тип ДвоичныеДанные
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("dbf");
ДанныеФайла.Записать(ИмяВременногоФайла);
// Теперь мы можем работать с файлом локально на сервере
// ... логика обработки ...
КонецФункции
Этот метод полностью снимает проблему прав доступа к удаленным папкам, так как файл физически передается внутри HTTP-пакета.
Проанализируем также маску поиска, которая упоминалась в обсуждении: "*.dbf*". Использование звездочки в конце расширения может привести к неожиданным результатам. Например, под такую маску попадут файлы data.dbf.bak или временные файлы report.dbf.tmp.
Рекомендуем использовать строгую маску, чтобы избежать ошибок при дальнейшей обработке объектов Файл:
// Более правильный вариант поиска
ИскомыеФайлы = НайтиФайлы(ПутьПоиска, "*.dbf", Ложь);
// Ложь указывает на то, что поиск в подпапках не требуется
Чтобы ваш поиск файлов через веб-сервис работал безотказно, придерживайтесь следующих правил:
\\server\share)./).ДвоичныеДанные.Применяя эти шаги, вы обеспечите надежную работу ваших интеграционных механизмов и избежите трудноуловимых ошибок, связанных с контекстом выполнения 1С.