Работа с сетевыми ресурсами на стороне сервера 1С:Предприятие — одна из классических задач, с которой сталкиваются разработчики при автоматизации выгрузки файлов или интеграции систем. Основная сложность заключается в том, что код, успешно работающий на клиенте (в интерактивном сеансе пользователя), часто отказывается работать в фоновом задании или в процедурах &НаСервере. Рассмотрим подробно причины возникновения этих проблем и разберем проверенные способы их решения.
Проанализируем ситуацию: когда вы запускаете команду КомандаСистемы или создаете объект WScript.Shell на клиенте, они исполняются в контексте вашего текущего пользователя Windows. Однако серверный код исполняется службой 1С:Предприятие. По умолчанию эта служба запускается от имени специального локального пользователя (например, USR1CV8) или системной учетной записи. Выясним основные причины неудач:
USR1CV8) не имеет прав в доменной сети. Ему «неизвестны» внешние пути, пока не будет пройдена явная авторизация.Рассмотрим способы преодоления этих ограничений.
Как показывает практика, использование PowerShell через WScript.Shell является наиболее гибким методом. Проанализируем пример кода, который позволяет не только выполнить команду net use, но и корректно получить результат ее выполнения, обработав кодировку.
Для начала создадим вспомогательную функцию для декодирования ответа консоли. Это важно, так как Windows PowerShell и командная строка часто возвращают текст в кодировке IBM866, которую 1С не понимает напрямую.
Функция ДекодерНаСервере(Текст, КодировкаНачальная = "IBM866", КодировкаКонечная = "utf-8") Экспорт
// Используем ADODB.Stream для перекодирования потока текста
Поток = Новый COMОбъект("ADODB.Stream");
Поток.Type = 2; // Text
Поток.Charset = КодировкаНачальная;
Поток.Open();
Поток.WriteText(Текст);
Поток.Position = 0;
Поток.Charset = КодировкаКонечная;
Результат = Поток.ReadText();
Поток.Close();
Возврат Результат;
КонецФункции
Теперь разберем основную логику выполнения PowerShell-команды. Использование метода Exec позволяет нам дождаться завершения процесса и прочитать потоки StdOut (вывод) и StdErr (ошибки).
Функция ВыполнитьКомандуPowerShell(КомандаPS) Экспорт
WSS = Новый COMОбъект("WScript.Shell");
// Формируем строку запуска PowerShell
ПолнаяКоманда = "powershell -Command """ + КомандаPS + """";
Процесс = WSS.Exec(ПолнаяКоманда);
// Ожидаем завершения выполнения
Пока Процесс.Status = 0 Цикл
// Можно добавить небольшую паузу, если команда длительная
КонецЦикла;
Результат = Процесс.StdOut.ReadAll();
Возврат ДекодерНаСервере(Результат);
КонецФункции
Для подключения диска мы будем использовать стандартную утилиту net use. Рассмотрим функцию, которая авторизует пользователя на сервере:
Функция ПодключитьСетевойДиск(БукваДиска, СетевойПуть, Пользователь, Пароль) Экспорт
// Формируем команду: net use Z: \\Server\Folder Password /user:Domain\User
Команда = "net use " + БукваДиска + " " + СетевойПуть + " " + Пароль + " /user:" + Пользователь;
Возврат ВыполнитьКомандуPowerShell(Команда);
КонецФункции
Создание виртуальных букв дисков (например, Q:) на сервере считается «плохим тоном» и часто приводит к конфликтам. Если несколько фоновых заданий попытаются использовать одну и ту же букву, возникнет ошибка «Имя локального устройства уже используется». Посмотрим на более надежный вариант — авторизацию на сетевом ресурсе по его прямому адресу (UNC).
После выполнения команды net use \\Server\Share /user:User Password сессия службы 1С получает доступ к этому пути до момента перезапуска службы или удаления подключения. Рассмотрим код:
КодВозврата = Неопределено;
СетевойПуть = "\\192.168.1.100\Exchange";
Логин = "Domain\Admin";
Пароль = "P@ssw0rd123";
// Запускаем авторизацию без привязки буквы
Команда = "net use " + СетевойПуть + " " + Пароль + " /user:" + Логин;
ЗапуститьПриложение(Команда, , Истина, КодВозврата);
Если КодВозврата = 0 Тогда
// Теперь мы можем обращаться к файлам напрямую
КопироватьФайл(ПутьКЛокальномуФайлу, СетевойПуть + "\data.xml");
Иначе
Сообщить("Ошибка авторизации. Код: " + КодВозврата);
КонецЕсли;
Проанализируем преимущества этого подхода: мы не занимаем буквы дисков, и нам не нужно следить за тем, свободна ли буква Z: или X: в текущий момент.
В некоторых случаях удобнее использовать специализированный COM-объект WScript.Network. Его метод MapNetworkDrive позволяет гибко управлять подключениями. Однако стоит помнить, что на сервере этот метод часто отрабатывает «тихо» — диск создается в контексте службы, и вы не увидите его в проводнике сервера.
Процедура ПодключитьДискЧерезWsh(Буква, Путь, Логин, Пароль)
Попытка
Network = Новый COMОбъект("WScript.Network");
// Пятый параметр True означает сохранение подключения после перезагрузки
Network.MapNetworkDrive(Буква, Путь, Ложь, Логин, Пароль);
Исключение
Инфо = ИнформацияОбОшибке();
Сообщить("Не удалось подключить диск: " + Инфо.Описание);
КонецПопытки;
КонецПроцедуры
Важный момент: если вы получили ошибку «Имя локального устройства уже используется», это значит, что в текущей сессии службы диск с такой буквой уже был подключен ранее. В этом случае необходимо сначала выполнить RemoveNetworkDrive.
Выясним, как сделать работу с сетью на сервере максимально стабильной:
1C:Enterprise 8.3 Server Agent от имени доменной учетной записи, у которой уже есть права на нужные сетевые папки. В этом случае никакие команды net use в коде вообще не понадобятся.mklink /D C:\RemoteData \\Server\Share. Для 1С это будет выглядеть как обычная локальная папка, и вся сложность сетевой авторизации ляжет на уровень операционной системы.net use /delete в блоке Попытка...КонецПопытки.Подведем итог: для разовых задач в регламентных заданиях лучше всего подходит Способ 2 (UNC-пути), так как он минимизирует риски конфликтов имен устройств и не требует сложной настройки окружения сессии.