При работе с 1С:Предприятие в режиме удаленного рабочего стола (RDP) программисты часто сталкиваются с ситуацией, когда выгрузка данных в файл (XML, Excel или текстовый формат) завершается ошибкой «Каталог не обнаружен» или «Неправильный путь к файлу». Ситуация выглядит парадоксально: пользователь видит диск «D:» или проброшенный ресурс \\tsclient\D в проводнике терминальной сессии, но программа отказывается записывать туда данные. Разберем подробно, почему это происходит и как правильно организовать работу с файлами в клиент-серверной архитектуре.
Для начала проанализируем ситуацию с точки зрения архитектуры 1С. В терминальном режиме запуск программы может происходить по-разному, но ключевым фактором является контекст выполнения кода. Если ваша процедура выгрузки помечена директивой &НаСервере, то исполнителем кода является не ваш компьютер и даже не ваша активная RDP-сессия, а служба 1C:Enterprise 8 Server Agent.
Рассмотрим основные причины, по которым сервер «не видит» пути:
D:\1c\vigr.xml, сервер ищет этот диск на своих физических ресурсах. Если на сервере 1С нет диска «D» или на нем отсутствует указанная папка, возникнет ошибка.USR1CV8). У этой записи нет прав на доступ к вашим личным папкам внутри RDP-сессии и, тем более, к сетевым ресурсам без явной настройки.\\tsclient\C — это виртуальные пути, создаваемые протоколом RDP для проброса ваших локальных дисков в сессию. Эти пути существуют только «внутри» сеанса конкретного пользователя. Служба сервера 1С находится «снаружи» этого сеанса и физически не может достучаться до \\tsclient.Если нам необходимо, чтобы файл записывался напрямую на сетевой ресурс или локальный диск сервера, мы должны убедиться, что служба сервера 1С имеет на это права. Проанализируем шаги по настройке:
Во-первых, выясним, под каким пользователем запущена служба 1С. Это можно сделать через «Панель управления» — «Администрирование» — «Службы». Найдем службу Агент сервера 1С:Предприятия. Если в колонке «Вход от имени» указано LocalSystem или USR1CV8, то доступ к сетевым папкам будет закрыт.
Во-вторых, создадим на сервере специальную папку, например C:\1C_Exchange\, и предоставим пользователю USR1CV8 полные права на чтение и запись в эту папку. В коде 1С при этом следует указывать именно этот локальный путь сервера.
В-третьих, если требуется выгрузка на другой сервер в сети, необходимо перенастроить запуск службы 1С от имени доменного пользователя, у которого есть права доступа к целевому сетевому ресурсу.
Иногда проблема кроется в настройках самого терминального клиента. Посмотрим, как проверить доступность локальных дисков:
Важный нюанс: Если даже после этих настроек путь \\tsclient\D\ не работает, возможно, на сервере действуют групповые политики (GPO), запрещающие перенаправление дисков. В этом случае необходимо обратиться к системному администратору.
Это самый надежный и универсальный способ. Рассмотрим сценарий: нам нужно выгрузить данные на сервере (так как там база и вся логика), но сохранить файл на локальный компьютер пользователя. Напрямую сервер записать файл на клиент не может. Поэтому мы разберем алгоритм с использованием временного хранилища. Для ручного интерактивного обмена между средами можно использовать файловый менеджер для обмена файлами между клиентом и сервером 1С.
Посмотрим на пример кода, который решает эту задачу. Сначала мы формируем данные на сервере, сохраняем их во временный файл, а затем передаем этот файл на клиент.
&НаСервере
Функция СформироватьФайлНаСервере()
// Создаем временное имя файла на сервере
ИмяФайлаСервер = ПолучитьИмяВременногоФайла("xml");
// Здесь ваша логика выгрузки, например:
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ИмяФайлаСервер);
// ... заполнение XML ...
ЗаписьXML.Закрыть();
// Помещаем файл во временное хранилище
ДанныеФайла = Новый ДвоичныеДанные(ИмяФайлаСервер);
АдресХранилища = ПоместитьВоВременноеХранилище(ДанныеФайла, ЭтаФорма.УникальныйИдентификатор);
// Удаляем временный файл с сервера после помещения в хранилище
УдалитьФайлы(ИмяФайлаСервер);
Возврат АдресХранилища;
КонецФункции
&НаКлиенте
Процедура Выгрузить(Команда)
// 1. Вызываем серверную функцию для формирования файла
Адрес = СформироватьФайлНаСервере();
// 2. Определяем, куда сохранить файл на клиенте
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
Диалог.Фильтр = "Файлы XML (*.xml)|*.xml";
Если Диалог.Выбрать() Тогда
ПутьКФайлу = Диалог.ПолноеИмяФайла;
// 3. Получаем данные из хранилища и записываем на клиентский диск
Данные = ПолучитьИзВременногоХранилища(Адрес);
Данные.Записать(ПутьКФайлу);
Сообщить("Файл успешно выгружен в: " + ПутьКФайлу);
КонецЕсли;
КонецПроцедуры
Рассмотрим подробнее, что происходит в этом коде. Функция ПолучитьИмяВременногоФайла() на сервере гарантирует, что у службы 1С будут права на запись, так как она использует системную временную папку профиля пользователя службы. Использование ПоместитьВоВременноеХранилище() позволяет передать двоичные данные файла через сетевой протокол 1С, игнорируя ограничения файловой системы RDP. Дополнительные примеры и нюансы рассмотрены в руководстве по работе с файлами в управляемых формах клиент-серверной 1С 8.3.
Часто возникает обратная задача: пользователь выбирает файл на своем компьютере через RDP, а программа должна его прочитать. Выясним, как это сделать правильно, избегая ошибки «Каталог не обнаружен».
Проанализируем ситуацию: метод Объект.Прочитать() или Новый ЗаписьТекста не сработает на сервере, если ему передать путь C:\MyDocuments\file.xlsx с клиентского ПК. Нужно сначала переместить файл в контекст сервера.
&НаКлиенте
Процедура ЗагрузитьФайл(Команда)
ПараметрыПомещения = Новый ПараметрыПомещенияФайлов;
ПараметрыПомещения.Интерактивно = Истина;
ПараметрыПомещения.Заголовок = "Выберите файл для загрузки на сервер";
// Используем асинхронный метод для современных платформ (8.3.15+)
ОписаниеОповещения = Новый ОписаниеОповещения("ПослеЗавершенияЗагрузки", ЭтотОбъект);
НачатьПомещениеФайлаНаСервер(ОписаниеОповещения, , , , , ЭтаФорма.УникальныйИдентификатор);
КонецПроцедуры
&НаКлиенте
Процедура ПослеЗавершенияЗагрузки(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры) Экспорт
Если Результат Тогда
// Файл уже на сервере во временном хранилище
ОбработатьФайлНаСервере(Адрес);
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ОбработатьФайлНаСервере(Адрес)
// Получаем двоичные данные из хранилища
Данные = ПолучитьИзВременногоХранилища(Адрес);
// Создаем временный файл на диске сервера, чтобы 1С могла его прочитать
ИмяВремФайла = ПолучитьИмяВременногоФайла("xlsx");
Данные.Записать(ИмяВремФайла);
// Теперь сервер может спокойно работать с файлом локально
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(ИмяВремФайла);
// Не забываем подчищать за собой
УдалитьФайлы(ИмяВремФайла);
КонецПроцедуры
Если ваш сервер 1С работает под управлением Linux, а пользователи подключаются через RDP к промежуточному Windows-серверу (или используют веб-клиент), ситуация усложняется. Пути вида D:\data\ в принципе невозможны в Linux. В этом случае:
cifs-utils./Export/ и /export/ — это разные каталоги).Подводя итог, можно сказать, что ошибка «Каталог не обнаружен» в RDP — это не баг платформы, а следствие работы механизмов безопасности и разделения контекстов. Чтобы ваша выгрузка работала стабильно, придерживайтесь следующих правил:
\\tsclient.&НаКлиенте.&НаСервере, предварительно передав файл через временное хранилище.1C:Enterprise 8 Server Agent и есть ли у нее физический доступ к папкам на дисках сервера.Следуя этим методикам, вы обеспечите бесперебойную работу обменов данными даже в самых сложных терминальных инфраструктурах.