Почему возникает ошибка «Permission denied» при создании каталога в фоновом задании 1С и как её исправить?

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

При разработке в среде «1С:Предприятие» программисты часто сталкиваются с ситуацией, когда код, написанный и протестированный в интерактивном режиме (на клиенте), работает безупречно, но при переносе его в фоновое или регламентное задание внезапно завершается аварийно. Типичный пример такой проблемы — ошибка создания каталога при использовании метода СоздатьКаталог() или перемещении файлов.

В этой статье мы подробно разберем, почему возникает ошибка доступа к файловой системе с кодом 13(0x0000000D): Permission denied, проанализируем разницу в контекстах выполнения «Клиент — Сервер» и рассмотрим несколько надежных способов решения этой проблемы.

Выясним причину этой ошибки на примере реального кейса из практики разработчиков.

---

Анализ исходной ситуации и кода

Рассмотрим исходный код обработки, которая должна сканировать определенную директорию, формировать список вложенных папок, создавать новый каталог с именем, содержащим текущую дату и время, и перемещать туда данные:


Процедура УдалитьКаталоги(Кнопка)
    Таблица.Очистить();
    НомерЭлемента = 0;
    КаталогЗапуска = "D:\TEST";
    МассивЭлементов = НайтиФайлы(КаталогЗапуска, "*", Ложь); // Получаем файлы и каталоги
    
    Для Каждого Элемент Из МассивЭлементов Цикл
        НомерЭлемента = НомерЭлемента + 1;
        Если Элемент.ЭтоКаталог() И Элемент.Имя <> "На удаление" И Элемент.Имя <> "temp" Тогда
            СтрокаТаблицы = Таблица.Добавить();
            СтрокаТаблицы.Каталог = Элемент.Имя;
            СтрокаТаблицы.Путь = Элемент.ПолноеИмя + "\";
        КонецЕсли;
    КонецЦикла;
    
    КаталогДатаУдаления = КаталогЗапуска + "\На удаление\\" + СтрЗаменить(ТекущаяДата(), ":", "-") + "\";
    СоздатьКаталог(КаталогДатаУдаления);
    // Продолжение логики перемещения файлов
КонецПроцедуры;

Когда этот код вызывается интерактивно (например, нажатием кнопки на форме в толстом или тонком клиенте), все работает отлично. Каталоги создаются, файлы перемещаются. Однако при попытке перенести этот код в общий модуль для выполнения в рамках фонового задания система генерирует исключение следующего вида:


{ОбщийМодуль.ФоновыеЗадания.Модуль(189)}: Ошибка при вызове метода контекста (СоздатьКаталог)
    СоздатьКаталог(КаталогДатаУдаления);    
по причине:
Ошибка создания каталога
по причине:
Ошибка доступа к файлу 'D:'. 13(0x0000000D): Permission denied

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

---

Причина 1: Контекст выполнения «Сервер <> Рабочая станция»

Самая распространенная ошибка начинающих разработчиков 1С — это заблуждение, что фоновое задание выполняется на компьютере пользователя и имеет те же права, что и текущая учетная запись Windows. Это не так.

Любое фоновое или регламентное задание выполняется исключительно на стороне сервера «1С:Предприятия» (в контексте процесса rphost).

Это приводит к следующим последствиям:

---

Причина 2: Ловушка сетевых дисков (Mapped Drives)

Если диск D:, к которому обращается фоновое задание, является сетевым ресурсом, подключенным в операционной системе как сетевой диск (например, через проводник под учетной записью администратора), фоновое задание его просто «не увидит».

Служба сервера 1С запускается в изолированной системной сессии (Сессия 0). В этой сессии сетевые диски, смонтированные интерактивными пользователями, отсутствуют. Попытка обратиться к диску D:\ из фонового задания вызовет ошибку доступа, поскольку операционная система сервера считает, что этого диска не существует или он недоступен для службы.

---

Причина 3: Кроссплатформенность (Linux + PostgreSQL)

Если в вашей ИТ-инфраструктуре используется сервер 1С под управлением ОС Linux (что крайне популярно в связке с СУБД PostgreSQL), то попытка выполнить код с путями вида D:\TEST\ гарантированно приведет к ошибке.

ОС Linux не использует буквы дисков (такие как C:, D:) и обратные слэши (\). Для Linux путь D:\TEST\ASS — это некорректная строка. Система попытается создать директорию с таким странным именем внутри своей рабочей папки, что завершится ошибкой отсутствия прав доступа.

---

Решение проблемы: Способы и рекомендации

Рассмотрим подробнее четыре эффективных способа решения данной проблемы в зависимости от архитектуры вашей системы.

Способ 1. Предоставление прав учетной записи службы 1С

Если сервер 1С работает под управлением ОС Windows, и папка действительно локальная (физический диск сервера), необходимо настроить права доступа:

  1. Выясните, под каким пользователем запущена служба 1C:Enterprise 8 Server Agent (Агент сервера 1С:Предприятия). Для этого откройте оснастку «Службы» (services.msc), найдите службу 1С и перейдите во вкладку «Вход в систему». Обычно там указан пользователь .\USR1CV8.
  2. Перейдите в проводнике к диску D:, нажмите правой кнопкой мыши на папку TEST (или на сам корень диска D:, если это необходимо) и выберите «Свойства» -> вкладка «Безопасность».
  3. Нажмите кнопку «Изменить» и добавьте пользователя USR1CV8 (или того пользователя, который указан в параметрах запуска службы).
  4. Предоставьте этому пользователю права «Изменение» (Modify), «Чтение и выполнение», «Список содержимого папки» и «Запись».
  5. Важно: Убедитесь, что у пользователя службы есть право на «Обход перекрестной проверки» (Bypass Traverse Checking) в групповых политиках безопасности Windows. Без этого права процесс не сможет обратиться к вложенной папке, если у него нет прав на просмотр корневого каталога диска.

Способ 2. Использование сетевых путей в формате UNC

Если вам необходимо работать с сетевым каталогом, полностью откажитесь от использования букв дисков. Вместо путей формата D:\TEST используйте полные UNC-пути:

КаталогЗапуска = "\\ИмяСервера\ИмяРесурса\TEST";

В этом случае на сервере-источнике (где физически расположена папка) необходимо предоставить права доступа на уровне сетевого общего ресурса (Share Permissions) и на уровне файловой системы (NTFS Permissions) для учетной записи, под которой работает сервер 1С.

Примечание: Если служба сервера 1С работает под локальной учетной записью (например, LocalSystem или локальный USR1CV8), она не сможет авторизоваться на другом сервере в сети. В таком случае службу сервера 1С необходимо перевести на запуск под доменной учетной записью (Active Directory) и дать этой учетной записи права на сетевую папку.

Способ 3. Переход на платформонезависимый код (для Linux-серверов)

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

  1. Используйте метод ПолучитьРазделительПути() вместо жестко прописанных символов "\" или "/".
  2. Определяйте тип платформы во время выполнения кода.

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


Разделитель = ПолучитьРазделительПути();
Если СистемнаяИнформация.ТипПлатформы = ТипПлатформыКадровогоУчета.Linux Тогда // Пример для общего понимания платформы
    КаталогЗапуска = "/media/share/TEST";
Иначе
    КаталогЗапуска = "D:\TEST";
КонецЕсли;

На Linux-сервере также необходимо выдать права на папку процессам 1С. Для этого в терминале Linux выполните команды:


sudo chown -R usr1cv8:grp1cv8 /media/share/TEST
sudo chmod -R 775 /media/share/TEST

Способ 4. Использование временных каталогов (Рекомендуемый подход)

Очень часто создание папок требуется для промежуточных манипуляций (например, сборка файлов перед отправкой по почте или архивация). Лучшая практика в этом случае — использовать временные папки самой платформы 1С.

Метод ПолучитьИмяВременногоФайла() гарантированно возвращает путь, на работу с которым у процесса rphost точно есть полные права. Этот путь ведет в системную временную директорию профиля пользователя службы 1С (например, C:\Windows\Temp или /tmp).

Разберем, как переписать исходную логику с использованием безопасных временных файлов:


// Получаем системный путь к временному каталогу сервера
ВременныйКаталог = КаталогВременныхФайлов(); 
УникальноеИмяПапки = ВременныйКаталог + "На_Удаление_" + Формат(ТекущаяДата(), "ДФ=yyyyMMdd_HHmmss");

// Создаем временную директорию
СоздатьКаталог(УникальноеИмяПапки);

// Производим любые действия с файлами внутри этой папки...

// По завершении работы удаляем временный каталог со всем содержимым
УдалитьФайлы(УникальноеИмяПапки);

Использование этого подхода полностью исключает возникновение ошибок прав доступа (Permission denied), так как операционная система сервера изначально предоставляет службе 1С неограниченный доступ к её собственной временной директории.

---

Резюме

Мы проанализировали проблему создания каталогов в фоновом задании 1С. Для стабильной работы ваших фоновыx процедур всегда придерживайтесь трех золотых правил разработчика:

← На главную