При разработке и администрировании систем на платформе 1С:Предприятие специалисты часто сталкиваются с ситуацией, когда код, предназначенный для копирования или чтения файлов, прекрасно работает на локальном компьютере разработчика, но вызывает критическую ошибку при переносе на сервер. Типичный сценарий: необходимо скопировать файл из сетевой папки общего доступа типа \\server\share\file.pdf во временный каталог сервера или прочитать его в двоичные данные. При выполнении кода на сервере система возвращает ошибку: «Ошибка при вызове метода контекста (КопироватьФайл)» или аналогичный сбой при инициализации объекта Новый ДвоичныеДанные.
В этой статье мы подробно разберем, почему возникает данная проблема, проанализируем механизмы работы сервера 1С с сетевым окружением и предложим несколько надежных вариантов решения — как на уровне администрирования операционной системы Windows, так и на уровне изменения программного кода 1С.
Для того чтобы понять суть проблемы, проанализируем контекст выполнения кода. Когда мы запускаем код в режиме клиента (на рабочем месте пользователя), все операции с файлами выполняются от имени текущего пользователя Windows, вошедшего в систему. Если у этого пользователя есть права доступа к сетевой папке \\server\share\, то копирование происходит успешно.
Однако, когда код выполняется в процедуре или функции с директивой &НаСервере (или в серверном модуле), управление передается серверной службе 1С:Предприятия. В этот момент выполнение файловых операций происходит от имени той учетной записи Windows, под которой запущена служба сервера 1С, а вовсе не от имени пользователя, сидящего за компьютером.
По умолчанию при установке платформы 1С:Предприятие создается локальная служебная учетная запись USR1CV8. Особенность локальной учетной записи заключается в том, что она существует только в рамках конкретного физического сервера, на котором установлена 1С. Внешний файловый сервер \\server ничего не знает о существовании локального пользователя USR1CV8 другого компьютера и, естественно, блокирует любые попытки доступа к своим сетевым ресурсам.
Аналогичная проблема возникает, если служба запущена под системной учетной записью LocalSystem (Локальная система). В сети домена Active Directory такой сервер пытается авторизоваться под своей учетной записью компьютера (вида ДОМЕН\ИМЯ_КОМПЬЮТЕРА$), которой по умолчанию также закрыт доступ к сетевым каталогам.
Прежде чем переходить к настройке прав, нам необходимо точно определить, от имени какого пользователя работает серверная служба. Разберем по шагам, как это сделать в ОС Windows:
services.msc и нажмите кнопку «ОК». Откроется стандартная оснастка управления службами Windows.1C:Enterprise 8.3 Server Agent)..\USR1CV8 или LocalSystem), для которой нам нужно будет настроить права доступа.ragent.exe.Для проверки того, действительно ли проблема кроется в правах конкретного пользователя, можно запустить командную строку от имени этого пользователя на сервере 1С и выполнить тестовое копирование с помощью команды:
runas /user:USR1CV8 cmd
copy "\\server\share\20190703\M\CMR 1,96 кг.pdf" "%Temp%\test.pdf"
Если команда возвращает ошибку «Доступ ограничен» или «Путь не найден», то диагноз поставлен верно: у службы сервера 1С нет сетевых прав.
Если ваша корпоративная сеть работает в рамках домена Active Directory, это самый правильный и безопасный способ решения проблемы. Рассмотрим алгоритм действий:
domain\usr_1c_services. Для этого пользователя желательно установить флаг «Срок действия пароля не ограничен».\\server в настройках общего доступа к сетевой папке (вкладка «Доступ» и вкладка «Безопасность» в свойствах папки) добавьте созданного доменного пользователя и предоставьте ему необходимые права (как минимум — «Чтение», при необходимости записи — «Изменение»).services.msc, перейдите в свойства службы «Агент сервера 1С:Предприятия».domain\usr_1c_services и введите его пароль. Нажмите кнопку «Применить».Performance Log Users и имеет права на чтение/запись в каталоги C:\Program Files\1cv8\ и C:\ProgramData\1C\).После перезапуска службы все серверные вызовы метода КопироватьФайл() к сетевым ресурсам будут успешно авторизоваться под учетной записью домена.
Если у вас нет домена Active Directory, а сервер 1С и файловый архив находятся на разных компьютерах в одной локальной сети (рабочей группе), доменная авторизация невозможна. В этом случае мы применим метод «зеркальных» учетных записей:
USR1CV8, пароль: MyPassword123). Если пароль пустой или неизвестен, задайте службе конкретный сложный пароль в управлении пользователями Windows.\\server и создайте там локального пользователя с абсолютно таким же именем и паролем (имя: USR1CV8, пароль: MyPassword123).USR1CV8 и предоставьте ему права чтения и записи.При попытке обращения сервера 1С к сетевому каталогу операционная система Windows автоматически сопоставит имена пользователей и пароли, выполнив так называемую сквозную аутентификацию (pass-through authentication), и предоставит доступ к файлу.
Если серверная служба 1С запущена под учетной записью LocalSystem в доменной среде, вы можете не создавать новых пользователей. В этом случае субъектом доступа в сети выступает сам компьютер, на котором работает 1С:
SERVER1C) и нажмите «Проверить имена». Имя преобразуется в вид SERVER1C$.Иногда даже при верной настройке прав сетевой доступ блокируется локальной политикой безопасности Windows на целевом сервере. Разберем, как это проверить:
gpedit.msc (или через администрирование локальной политики безопасности secpol.msc).Что делать, если у вас нет прав администратора для изменения настроек операционной системы, а файлы копировать необходимо? Мы можем изменить архитектуру взаимодействия с файлами в коде 1С, полностью отказавшись от прямого обращения сервера к сетевому ресурсу. Решением является перенос чтения файла на сторону клиентского приложения, у которого гарантированно есть доступ к сетевому диску, с последующей передачей данных на сервер через Временное Хранилище.
Проанализируем пример реализации такого подхода. Вместо прямого вызова серверного метода копирования мы реализуем асинхронную передачу файла.
Ниже представлен пример кода для управляемых форм 1С:
&НаКлиенте
Асинхронная Процедура СкопироватьФайлЧерезКлиент()
// Путь к файлу на сетевом ресурсе, доступном пользователю
ПутьКСетевомуФайлу = "\\server\share\20190703\M\CMR 1.96 kg.pdf";
ИмяФайлаПриемника = "CMR_Copy.pdf";
// Проверим существование файла на клиенте
ФайлНаДиске = Новый Файл(ПутьКСетевомуФайлу);
Если Не ФайлНаДиске.Существует() Тогда
Предупреждение("Сетевой файл не найден или к нему нет доступа!");
Возврат;
КонецЕсли;
// Помещаем файл во временное хранилище на клиенте
ОписаниеФайла = Новый ОписаниеПередаваемогоФайла(ПутьКСетевомуФайлу);
МассивФайлов = Новый Массив;
МассивФайлов.Добавить(ОписаниеФайла);
РезультатПередачи = Ждать ПоместитьФайлыВоВременноеХранилищеАсинх(МассивФайлов);
Если РезультатПередачи.Количество() > 0 Тогда
АдресВХранилище = РезультатПередачи[0].Хранилище;
// Передаем адрес во временном хранилище на сервер для дальнейшей обработки
ОбработатьФайлНаСервере(АдресВХранилище, ИмяФайлаПриемника);
ПоказатьПредупреждение(, "Файл успешно скопирован и обработан на сервере!");
КонецЕсли;
КонецПроцедуры
Теперь рассмотрим серверную часть процедуры, которая принимает адрес временного хранилища, извлекает двоичные данные и сохраняет их в локальную временную папку сервера, к которой у процесса 1С гарантированно есть доступ:
&НаСервере
Процедура ОбработатьФайлНаСервере(Знач АдресВХранилище, Знач ИмяФайлаПриемника)
// Получаем двоичные данные файла из временного хранилища сервера
ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(АдресВХранилище);
// Определяем локальный путь на сервере (например, каталог временных файлов службы)
ПутьПриемникаНаСервере = КаталогВременныхФайлов() + ИмяФайлаПриемника;
// Записываем файл на сервере
ДвоичныеДанныеФайла.Записать(ПутьПриемникаНаСервере);
// Далее мы можем прикрепить этот файл к справочнику, документу или отправить по почте
// Например, поместить в справочник "ПрисоединенныеФайлы"
// ... Код интеграции с вашей СУБД ...
// Очищаем временное хранилище
УдалитьИзВременногоХранилища(АдресВХранилище);
КонецПроцедуры
Преимущество этого метода очевидно: сервер 1С работает исключительно со своими локальными временными каталогами, куда запись разрешена по умолчанию. Передача файла по сети ложится на плечи платформы 1С через HTTP/TCP-протоколы взаимодействия клиента и сервера. Это полностью нивелирует проблему доменных прав доступа серверной операционной системы.
Как справедливо заметили участники обсуждения на форуме, при работе с сетевыми файлами и кроссплатформенными вызовами крайне желательно избегать использования спецсимволов, пробелов и кириллицы в именах файлов, если это возможно. Файлы с именами вроде CMR 1,96 кг.pdf могут некорректно обрабатываться некоторыми сетевыми протоколами или веб-серверами (например, IIS или Apache при публикации базы). Оптимально переименовывать файлы по стандарту латиницы без пробелов, заменяя их на нижнее подчеркивание или дефис (например, CMR_1-96_kg.pdf), что гарантирует стабильность работы файловых методов в любых операционных системах.