Почему не выполняется bat-файл с кодом Python из 1С на сервере и как это исправить?

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

Разберем классическую и очень распространенную ситуацию при интеграции 1С с внешними скриптами. Представим: вы написали отличный код на Python, создали для его запуска bat-файл (или пытаетесь запустить напрямую). Если запускать этот файл двойным кликом в операционной системе — всё отлично работает. Если вызывать его из 1С на клиенте с помощью метода ЗапуститьПриложение — тоже всё успешно выполняется. Но стоит только перенести выполнение кода на сервер 1С, как скрипт перестает отрабатывать, зависает или выдает неочевидные ошибки.

Давайте подробно проанализируем причины такого поведения и рассмотрим надежные способы решения этой задачи, чтобы ваш код безотказно работал на сервере 1С.

Выясним причину: почему код не работает на сервере 1С?

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

Однако служба "Агент сервера 1С:Предприятия" по умолчанию запускается под специальной системной учетной записью, как правило, это USR1CV8. И здесь возникают две главные трудности:

  1. Расположение интерпретатора и библиотек: По умолчанию современные версии Python устанавливаются в папку пользователя (например, в AppData\Local\Programs\Python). Пользователь USR1CV8 физически не имеет доступа к этой директории. То же самое касается библиотек, установленных через pip.
  2. Переменные окружения: Системная переменная PATH для пользователя службы может не содержать путь к python.exe, из-за чего вызов простой команды python script.py завершается ошибкой "не удается найти указанный файл".

В нашем случае разработчик пытался сделать импорт библиотеки shapefile (установленной через пакет pyshp). На сервере код зависал или падал, потому что библиотека была установлена локально для профиля разработчика.

Решение 1: Глобальная установка Python (из опыта на форуме)

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

  1. Полностью деинсталлируйте Python, который был установлен в директорию текущего пользователя.
  2. Запустите установщик Python заново и при установке обязательно выберите опцию установки для всех пользователей (Install for all users). В этом случае Python будет установлен в глобальную директорию, например, в C:\Program Files\Python или C:\Program Files\Python39.
  3. Запустите командную строку от имени Администратора.
  4. Установите нужные библиотеки глобально. Например: pip install pyshp. Библиотека запишется в папку C:\Program Files\Python\Lib\site-packages.
  5. Важно: Перезапустите службу сервера 1С! Службы Windows считывают переменные окружения только в момент старта. Если вы просто установили Python и добавили его в глобальный PATH, работающий сервер 1С об этом не узнает до перезапуска.

После этих шагов вызов интерпретатора через метод ЗапуститьПриложение на сервере должен завершаться успешно:


КомандаЗапуска = """C:\Program Files\Python39\python.exe"" D:\Projects\Python\ForCreatedShp.py";
ЗапуститьПриложение(КомандаЗапуска);

Решение 2: Использование виртуальных окружений (venv) - лучшая практика

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

  1. Создайте папку вашего проекта, например D:\Projects\Python\ и убедитесь, что у пользователя USR1CV8 есть права на чтение и выполнение файлов в этой папке.
  2. Создайте виртуальное окружение внутри этой папки командой: python -m venv D:\Projects\Python\venv
  3. Активируйте окружение и установите библиотеку pyshp конкретно в него.
  4. Теперь в коде 1С обращайтесь не к глобальному Python, а к исполняемому файлу виртуального окружения.

Пример вызова из 1С:


ПутьКPython = "D:\Projects\Python\venv\Scripts\python.exe";
ПутьКСкрипту = "D:\Projects\Python\ForCreatedShp.py";
ЗапуститьПриложение(ПутьКPython + " " + ПутьКСкрипту);

Этот подход гарантирует стабильность: переустановка глобального Python на сервере никак не сломает ваш рабочий скрипт.

Решение 3: Правильный отлов ошибок с помощью WScript.Shell

Разберем ситуацию, когда скрипт всё равно не работает, и нам нужно понять почему. Использование ЗапуститьПриложение не позволяет нам прочитать текст системной ошибки (например, если Python пишет ModuleNotFoundError). Автор темы пытался вставлять в скрипт команду input() для отладки, но для сервера это губительно — процесс просто повиснет в ожидании ввода, которого никогда не произойдет.

Рассмотрим надежный способ запуска с перехватом консольного вывода с помощью COM-объекта WScript.Shell и его метода Exec.


WshShell = Новый COMОбъект("WScript.Shell");
Команда = "D:\Projects\Python\venv\Scripts\python.exe D:\Projects\Python\ForCreatedShp.py";

Попытка
    Выполнение = WshShell.Exec(Команда);
    
    // Ждем завершения выполнения
    Пока Выполнение.Status = 0 Цикл
        ОбработкаПрерыванияПользователя();
    КонецЦикла;
    
    ТекстОшибки = Выполнение.StdErr.ReadAll();
    Результат = Выполнение.StdOut.ReadAll();
    
    Если ЗначениеЗаполнено(ТекстОшибки) Тогда
        Сообщить("Ошибка скрипта: " + ТекстОшибки);
    Иначе
        Сообщить("Скрипт выполнен. Результат: " + Результат);
    КонецЕсли;

Исключение
    Сообщить("Не удалось запустить COM-объект: " + ОписаниеОшибки());
КонецПопытки;

Используя этот метод, вы сразу получите в 1С полный текст ошибки, если на сервере не хватает прав, отсутствует библиотека или есть синтаксическая ошибка в самом коде Python.

Альтернативная современная архитектура: Микросервисы

Посмотрим на проблему чуть шире. Регулярный вызов сторонних консольных утилит через создание нового процесса операционной системы — это ресурсоемкая операция. Если вы пишете файл на диск, затем вызываете скрипт, затем скрипт читает файл, что-то делает и пишет новый файл, а 1С его считывает — это медленно и ненадежно в условиях высоких нагрузок.

Современной практикой является оборачивание Python-кода в легковесный веб-сервер. Вы можете использовать библиотеки Flask или FastAPI. В этом случае ваш Python-скрипт устанавливается как служба Windows и постоянно работает в фоновом режиме, слушая определенный порт (например, 8080).

Как это будет работать со стороны 1С:

  1. Вы формируете необходимые данные (например, JSON или CSV).
  2. Отправляете их с помощью объекта 1С HTTPСоединение обычным POST-запросом на localhost:8080/create_shape.
  3. Python моментально обрабатывает запрос в оперативной памяти и возвращает готовый результат в теле HTTP-ответа.

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

← На главную