В практике разработки на платформе 1С часто возникает задача передачи данных во внешние системы через общие сетевые ресурсы. Одной из типичных схем является формирование XML-файла и его последующее перемещение в сетевую папку. Однако разработчики часто сталкиваются с ситуацией, когда обычные текстовые файлы (.txt) копируются без проблем, а при попытке скопировать .xml система выдает ошибку "Разрешение отклонено" (Permission Denied). Разберем по шагам, почему это происходит и как правильно настроить процесс в клиент-серверном режиме работы.
Прежде всего, проанализируем, где именно исполняется код. Когда мы запускаем внешнюю обработку в клиент-серверной базе, код с директивой &НаСервере выполняется от имени учетной записи, под которой запущена служба "Агент сервера 1С:Предприятия". Это критически важный момент. Даже если вы авторизованы в Windows под учетной записью администратора, сервер 1С может работать под ограниченной системной учетной записью (например, USR1CV8 или NetworkService).
Выясним причину разного поведения файлов разных форматов. Рассмотрим ситуацию: .txt копируется, а .xml — нет. Это часто вводит в заблуждение, заставляя думать, что права доступа настроены верно. На самом деле, для сетевых ресурсов могут быть настроены политики безопасности, которые фильтруют содержимое или расширения файлов.
В коде автора часто фигурируют пути вида W:\Import\. Это типичная ошибка при работе на сервере. Сетевые диски (Mapped Drives) являются объектами сеанса конкретного пользователя. Служба 1С работает в так называемой "Сессии 0", где ваши подключенные диски W:, S: или Z: просто не существуют.
Решение: Всегда используйте полные сетевые пути в формате UNC. Разберем на примере изменения кода:
// Вместо использования буквы диска W:\
// Используем прямой сетевой путь \\ServerName\ShareName\
КодФункции = "Function copy | |Set objFSO = CreateObject(""Scripting.FileSystemObject"") |objFSO.CopyFile ""\\SourceServer\sw\1.xml"" , ""\\TargetServer\Import\"", true | |End Function";
Проанализируем механику записи XML. В 1С для этого обычно используются объекты ЗаписьXML. Если после завершения записи не был вызван метод Закрыть(), файл остается захваченным процессом rphost.exe. При попытке копирования через FileSystemObject операционная система откажет в доступе, так как дескриптор файла не освобожден.
Посмотрим на правильную последовательность действий в 1С:
Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл(ПутьКФайлу);
// ... логика записи данных ...
Запись.Закрыть(); // Обязательный шаг перед копированием!
Почему же .txt проходит? В системном администрировании существует роль FSRM (File Server Resource Manager). Она позволяет блокировать запись определенных типов файлов в сетевые папки. Часто администраторы разрешают текстовые логи, но запрещают структурированные данные (XML, скрипты, исполняемые файлы) для защиты от вирусов-шифровальщиков.
Также стоит проверить антивирус на сервере. XML-файл подвергается более глубокому анализу (парсингу) со стороны защитных систем. Если антивирус считает операцию подозрительной (скрипт MSScriptControl пытается записать .xml на удаленный ресурс), он может заблокировать именно эту операцию, игнорируя при этом простые .txt.
Использование MSScriptControl.ScriptControl для копирования файлов в современной платформе 8.3 избыточно и потенциально небезопасно. Платформа обладает мощным встроенным функционалом, который работает стабильнее и прозрачнее для системы прав. Рассмотрим использование метода КопироватьФайл().
Преимущество этого метода в том, что он выполняется в контексте сервера 1С напрямую, без создания дополнительных COM-объектов. Посмотрим на пример реализации:
&НаСервере
Процедура СкопироватьФайлНаСервер(ЛокальныйПуть, СетевойПуть)
// Используем UNC-путь для сетевого назначения
ИмяФайлаПриемника = "\\192.168.1.100\Public\Import\data.xml";
Попытка
КопироватьФайл(ЛокальныйПуть, ИмяФайлаПриемника);
ЗаписьЖурналаРегистрации("КопированиеФайла", УровеньЖурналаРегистрации.Информация, , , "Файл успешно скопирован");
Исключение
ИнформацияОбОшибке = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаписьЖурналаРегистрации("КопированиеФайла", УровеньЖурналаРегистрации.Ошибка, , , ИнформацияОбОшибке);
ВызватьИсключение "Не удалось скопировать файл: " + ИнформацияОбОшибке;
КонецПопытки;
КонецПроцедуры
Если даже встроенная функция выдает ошибку доступа, выполним следующую проверку:
USR1CV8).USR1CV8 права на "Запись" и "Изменение".Проанализируем еще один интересный способ проверки из обсуждения: попробуйте программно переименовать файл 1.xml в 1.txt перед копированием, скопировать его, а на стороне приемника переименовать обратно. Если такая схема сработает — значит, на сетевом ресурсе настроена жесткая блокировка расширений .xml.
Для стабильной работы системы придерживаемся следующих правил:
КопироватьФайл(), она более предсказуема в среде 1С.Z:, W:) в серверном коде. Только \\Server\Folder\file.xml.ЗаписьXML или ТекстовыйДокумент закрыты перед попыткой их перемещения.Соблюдение этих правил позволит избежать большинства проблем с правами доступа при работе с внешними файловыми ресурсами.