Как запустить внешнее приложение или скрипт из 1С на сервере и исправить ошибку "Обращение к процедуре как к функции"?

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

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

Разберем ошибку "Обращение к процедуре как к функции"

При использовании конструкции вида ЗапуститьПриложение("cmd /c node script.js", Каталог, Истина) разработчики иногда пытаются присвоить результат выполнения переменной или обернуть вызов в условие Если. Выясним причину падения кода: в платформе 1С метод ЗапуститьПриложение является процедурой, а не функцией. Он не возвращает результат выполнения.

Посмотрим на пример кода, который вызывает ошибку:


// ОШИБКА: Попытка получить результат от процедуры
Результат = ЗапуститьПриложение("cmd /c node " + СкриптРасшифровки, КаталогРасшифровки, Истина);

// ОШИБКА: Использование процедуры в логическом условии
Если ЗапуститьПриложение("cmd /c node " + СкриптРасшифровки, КаталогРасшифровки, Истина) Тогда
    // какой-то код
КонецЕсли;

Если нам необходимо получить статус завершения стороннего скрипта, воспользуемся четвертым параметром процедуры — КодВозврата. Синтаксически правильный вызов выглядит так:


КодВозврата = Неопределено;
// Передаем переменную в 4-й параметр
ЗапуститьПриложение("cmd /c node " + СкриптРасшифровки, КаталогРасшифровки, Истина, КодВозврата);

Если КодВозврата = 0 Тогда
    Сообщить("Скрипт выполнен успешно!");
Иначе
    Сообщить("Произошла ошибка, код: " + КодВозврата);
КонецЕсли;

Почему ЗапуститьПриложение плохо работает на сервере?

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

Права 1С против системных прав ОС (Windows/Linux)

Разберем популярное заблуждение: если скрипт не запускается на сервере, нужно обернуть вызов в УстановитьПривилегированныйРежим(Истина). Это не поможет.

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

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

  1. Дать пользователю USR1CV8 права на чтение и выполнение исполняемого файла (например, node.exe).
  2. Дать права на чтение, запись и изменение файлов в директории, с которой работает скрипт (в нашем случае это КаталогРасшифровки).

Давать серверному пользователю 1С полные администраторские права в операционной системе категорически не рекомендуется с точки зрения безопасности.

Надежные альтернативы для запуска скриптов на сервере 1С

Рассмотрим подробнее архитектурные решения и технические инструменты, которые следует использовать вместо ЗапуститьПриложение на стороне сервера.

Способ 1: Использование COM-объекта WScript.Shell (для серверов Windows)

Это классический и самый распространенный подход для запуска консольных утилит. Объект WScript.Shell позволяет скрыть окно командной строки и дождаться завершения процесса.


WshShell = Новый COMОбъект("WScript.Shell");

// Формируем команду запуска
Команда = "cmd /c node " + СкриптРасшифровки;

// Метод Run: 
// 0 - скрытое окно (не будет мелькать консоль)
// Истина - ожидать завершения процесса
КодВозврата = WshShell.Run(Команда, 0, Истина);

Если КодВозврата = 0 Тогда
    // Обрабатываем результат расшифровки
КонецЕсли;

Если скрипт Node.js выводит расшифрованные данные прямо в консоль (например, через console.log), мы можем перехватить этот текст напрямую, используя метод Exec:


WshShell = Новый COMОбъект("WScript.Shell");
Команда = "cmd /c node " + СкриптРасшифровки;

// Запускаем процесс
Процесс = WshShell.Exec(Команда);

// Читаем стандартный поток вывода (stdout)
ТекстРезультата = Процесс.StdOut.ReadAll();

// Читаем поток ошибок (stderr)
ТекстОшибки = Процесс.StdErr.ReadAll();

Если ПустаяСтрока(ТекстОшибки) Тогда
    // Используем ТекстРезультата
КонецЕсли;

Способ 2: Использование Библиотеки стандартных подсистем (БСП)

Если ваша конфигурация построена на базе БСП (например, ERP, УТ, БП, ЗУП), воспользуемся готовым и безопасным API. В БСП есть общий модуль ФайловаяСистема с экспортным методом ЗапуститьПрограмму, который отлично работает на сервере и берет на себя всю черновую работу.


ПараметрыЗапуска = ФайловаяСистема.ПараметрыЗапускаПрограммы();
ПараметрыЗапуска.ДождатьсяЗавершения = Истина;
ПараметрыЗапуска.СкрытьОкно = Истина;
ПараметрыЗапуска.ТекущийКаталог = КаталогРасшифровки;

КодВозврата = Неопределено;
ПотокВывода = "";
ПотокОшибок = "";

// Безопасный вызов через БСП
ФайловаяСистема.ЗапуститьПрограмму(
    "cmd /c node " + СкриптРасшифровки, 
    ПараметрыЗапуска, 
    КодВозврата, 
    ПотокВывода, 
    ПотокОшибок
);

Способ 3: Микросервисная архитектура (Web-сервис)

Как верно отметили системные архитекторы, вызывать сторонние утилиты через командную строку сервера баз данных — это "грязный" подход. Проанализируем более современную парадигму. Вместо того чтобы дергать скрипты через cmd, мы можем "обернуть" скрипт расшифровки (Node.js) в простой веб-сервер (например, с использованием фреймворка Express).

В этом случае схема работы будет следующей:

  1. Node.js работает как отдельная служба на порту (например, localhost:3000).
  2. 1С на сервере собирает данные (зашифрованный файл) и отправляет POST-запрос с помощью объекта HTTPСоединение на этот локальный сервис.
  3. Служба на Node.js расшифровывает данные и отдает их обратно в теле HTTP-ответа.
  4. 1С принимает ответ и сохраняет его в базу.

Такой подход полностью исключает проблемы с правами файловой системы, зависанием консольных окон и блокировками, а также позволяет легко масштабировать систему (например, вынести расшифровку на другой физический сервер). Для отладки и проверки подобных интеграций подойдёт обработка для тестирования HTTP-сервисов и отправки запросов.

← На главную