Часто при разработке фоновых заданий или серверных модулей возникает задача прочитать файл из сетевой папки или сохранить отчет на другой сервер. Однако стандартные методы 1С могут выдавать ошибку «Каталог не существует», даже если при ручном копировании всё работает. В этой статье мы подробно разберем, почему так происходит, и рассмотрим пошагово все способы решения этой проблемы.
Прежде чем приступать к коду, давайте проанализируем ситуацию с точки зрения операционной системы. Когда вы заходите на сервер под своей учетной записью и копируете файл «руками», вы работаете в своем интерактивном сеансе. Фоновое же задание 1С выполняется в контексте службы «Агент сервера 1С:Предприятия».
По умолчанию эта служба устанавливается от имени локального пользователя USR1CV8. Эта учетная запись «живет» только на текущем компьютере и не имеет никаких прав в доменной сети. Именно поэтому при попытке обратиться к пути \\Server2\Share сервер 1С получает отказ в доступе.
Кроме того, важно помнить: сетевые диски (например, диск Z:) существуют только внутри сеанса конкретного пользователя. Для службы 1С, работающей в «нулевой» сессии, никаких букв дисков не существует, даже если вы их подключили под своим логином.
Это самый правильный и «чистый» способ с точки зрения системного администрирования. Если серверу 1С нужно постоянно работать с сетевыми ресурсами, мы должны дать ему доменную учетную запись.
1C_Service).services.msc).После перезапуска службы 1С все методы работы с файлами, такие как КопироватьФайл() или НайтиФайлы(), начнут видеть сетевые ресурсы по UNC-путям.
Как мы уже выяснили, использовать буквы дисков (Z:\...) в серверном коде нельзя. Мы должны использовать полные сетевые имена. Давайте посмотрим на пример правильного обращения к файлу:
// Неправильно:
ПутьКФайлу = "Z:\Reports\Sales.xlsx";
// Правильно:
ПутьКФайлу = "\\ИмяСервераХранилища\ОбщаяПапка\Reports\Sales.xlsx";
ФайлНаДиске = Новый Файл(ПутьКФайлу);
Если ФайлНаДиске.Существует() Тогда
// Продолжаем работу
КонецЕсли;
Если сменить пользователя службы нет возможности (например, из-за политик безопасности компании), мы можем попробовать «представиться» удаленному серверу прямо из кода. Для этого воспользуемся объектом WScript.Network. Проанализируем пример кода, который временно подключает ресурс:
// Создаем объект для работы с сетевыми ресурсами
Network = Новый COMОбъект("WScript.Network");
ПутьКРесурсу = "\\Server2\ShareName";
Логин = "DOMAIN\UserName";
Пароль = "P@ssw0rd123";
Попытка
// Подключаем сетевой ресурс без назначения буквы диска
// Третий параметр Ложь - не сохранять подключение постоянно
Network.MapNetworkDrive("", ПутьКРесурсу, Ложь, Логин, Пароль);
// Теперь сервер 1С авторизован для этого пути
КопироватьФайл(ПутьКРесурсу + "\file.txt", "C:\Temp\file.txt");
// После работы желательно отключить ресурс
Network.RemoveNetworkDrive(ПутьКРесурсу);
Исключение
Сообщить("Ошибка авторизации: " + ОписаниеОшибки());
КонецПопытки;
Обратите внимание: Этот метод может работать нестабильно в высоконагруженных многопоточных системах, поэтому используйте его только как временное или вынужденное решение.
Рассмотрим еще один вариант авторизации — через вызов командной строки Windows. Это позволяет «объяснить» операционной системе, под какими данными нужно ходить на конкретный сервер.
// Формируем команду авторизации
Команда = "net use \\Server2\ShareName /user:DOMAIN\Login MyPassword";
// Выполняем команду в скрытом режиме и ждем завершения
ЗапуститьПриложение(Команда, , Истина);
// Теперь можно обращаться к файлу напрямую
Если НайтиФайлы("\\Server2\ShareName", "data.xml").Количество() > 0 Тогда
// Код обработки файла
КонецЕсли;
// После завершения можно сбросить авторизацию
ЗапуститьПриложение("net use \\Server2\ShareName /delete", , Истина);
Проанализируем несколько критических моментов, которые часто упускают из виду:
runas /user:DOMAIN\1C_Service cmd. В открывшемся окне введите dir \\Server2\ShareName. Если вы видите список файлов — значит, и 1С их увидит.В завершение подчеркнем: для стабильной работы системы всегда лучше один раз настроить службу 1С под доменной учетной записью, чем писать в коде пароли в открытом виде и использовать временные подключения. Это обеспечит максимальную производительность и безопасность вашего решения.