Как в 1С записать двоичные данные от имени учетной записи службы USR1CV8

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке интеграционных механизмов и выгрузке файлов на сетевой ресурс часто возникает задача сохранения данных от имени системной службы сервера 1С (обычно USR1CV8), а не текущего пользователя операционной системы. Разберем, почему метод ДвоичныеДанные.Записать() может создавать файлы под учетной записью клиента, и рассмотрим рабочие способы решения этой задачи.

Анализ проблемы: почему владельцем файла становится пользователь

Проанализируем типовую ситуацию: разработчик получает файл из временного хранилища и выполняет сохранение в сетевой каталог следующей конструкцией:


ДвоичныеДанныеВХ = ПолучитьИзВременногоХранилища(АдресВХ);
ДвоичныеДанныеВХ.Записать("\\АдресСервера\папка\" + ИмяФайла);

После выполнения операции владельцем созданного в файловой системе объекта оказывается учетная запись Windows того пользователя, который запустил сеанс 1С. Выясним основные причины такого поведения:

  1. Работа в файловой информационной базе. В файловом режиме директива &НаСервере является программной эмуляцией. Весь код фактически выполняется внутри клиентского процесса 1cv8c.exe или 1cv8.exe. Служба сервера 1С в этом сценарии не задействована, поэтому любые файловые операции происходят от имени текущего локального пользователя.
  2. Выполнение кода на клиенте. Если метод выгрузки вызван в клиентском контексте (&НаКлиенте), запись файла напрямую инициируется рабочей станцией пользователя.
  3. Особенности наследования прав в каталоге назначения. В операционных системах Windows при создании файла владельцем по умолчанию назначается субъект безопасности, выполняющий процесс записи.

Способ 1. Перенос выполнения в серверный контекст клиент-серверной базы

Рассмотрим поведение платформы в полноценном клиент-серверном режиме. В среде «клиент-сервер» любой вызов процедуры с директивой &НаСервере или &НаСервереБезКонтекста передается на сервер и обрабатывается рабочим процессом rphost.exe.

Так как процесс rphost.exe работает в контексте системной учетной записи службы 1С (USR1CV8), все операции с файловой системой на стороне сервера автоматически выполняются от имени этой службы.


&НаСервереБезКонтекста
Процедура СохранитьФайлНаСервере(АдресВХ, СетевойПуть, ИмяФайла)
    ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВХ);
    ПолныйПуть = СетевойПуть + "\" + ИмяФайла;
    ДвоичныеДанные.Записать(ПолныйПуть);
КонецПроцедуры

Важный нюанс сетевого доступа: по умолчанию учетная запись USR1CV8 является локальным пользователем сервера (.\USR1CV8). Локальный пользователь не имеет доступа к общим сетевым папкам на других серверах домена. Чтобы сервер 1С мог записывать файлы по пути вида \\АдресСервера\папка\, необходимо запускать службу сервера 1С под доменной учетной записью (Domain User) и предоставить ей права NTFS и доступ к общему ресурсу.

Способ 2. Использование фонового задания для мгновенной асинхронной записи

Если требуется гарантированно изолировать запись файла от сеанса пользователя и выполнить операцию асинхронно без блокировки интерфейса, используем механизм фоновых заданий через менеджер ФоновыеЗадания.

Разберем реализацию по шагам:

  1. Создаем экспортную процедуру в общем модуле с установленными флагами Сервер и Вызов сервера.
  2. Помещаем файл во временное хранилище и передаем его адрес в фоновое задание.
  3. Запускаем выполнение метода через ФоновыеЗадания.Выполнить().

Посмотрим на пример реализации серверного модуля:


// Процедура в общем модуле (например, ИнтеграцияФайловСервер)
Процедура ВыгрузитьФайлВКаталог(АдресВХ, ПолноеИмяФайла) Экспорт
    ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВХ);
    ДвоичныеДанные.Записать(ПолноеИмяФайла);
    УдалитьИзВременногоХранилища(АдресВХ);
КонецПроцедуры

Вызов фонового задания из формы или обработчика:


&НаКлиенте
Процедура СохранитьФайл(Команда)
    // Помещаем файл во временное хранилище на клиенте
    АдресФайла = ПоместитьФайлВХранилище();
    ЗапуститьФоновоеСохранение(АдресФайла, "Выгрузка.dat");
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ЗапуститьФоновоеСохранение(АдресФайла, ИмяФайла)
    ПараметрыЗадания = Новый Массив;
    ПараметрыЗадания.Добавить(АдресФайла);
    ПараметрыЗадания.Добавить("\\АдресСервера\папка\" + ИмяФайла);
    
    ФоновыеЗадания.Выполнить(
        "ИнтеграцияФайловСервер.ВыгрузитьФайлВКаталог", 
        ПараметрыЗадания, 
        , 
        "Выгрузка файла " + ИмяФайла
    );
КонецПроцедуры

Способ 3. Использование HTTP-сервисов для изоляции файловых операций

В распределенных системах или при необходимости работы из файловых баз передачу файлов можно организовать через встроенные HTTP-сервисы 1С:

  1. На стороне центральной базы публикуется HTTP-сервис, принимающий двоичные данные методом POST или PUT.
  2. Клиентский сеанс отправляет HTTP-запрос с телом файла на адрес сервиса.
  3. Серверный обработчик сервиса получает тело запроса (HTTPСервисЗапрос.ПолучитьТелоКакДвоичныеДанные()) и сохраняет его в целевой сетевой каталог.

Этот подход полностью абстрагирует клиента от файловой системы назначения и гарантирует, что запись в сетевую папку выполняется под учетной записью веб-сервера или пула приложений сервера 1С.

Способ 4. Корректировка владельца и прав средствами операционной системы

Если изменить архитектуру выгрузки невозможно, скорректировать владельца созданного файла можно системными средствами Windows. Для этого после сохранения файла выполняется команда с помощью метода ЗапуститьПриложение().

Рассмотрим пример использования системных утилит icacls и takeown:


&НаСервере
Процедура СменитьВладельцаФайла(ПутьКФайлу, ИмяНовогоВладельца)
    КомандаОС = СтрШаблон("icacls ""%1"" /setowner ""%2"" /T /C /Q", ПутьКФайлу, ИмяНовогоВладельца);
    ЗапуститьПриложение(КомандаОС, , Истина);
КонецПроцедуры

Обратите внимание: для успешной смены владельца учетная запись, от имени которой вызывается утилита, должна обладать привилегиями управления безопасностью (SeTakeOwnershipPrivilege или SeRestorePrivilege) в операционной системе.

← На главную