Разберем классическую и очень распространенную ситуацию при интеграции 1С с внешними скриптами. Представим: вы написали отличный код на Python, создали для его запуска bat-файл (или пытаетесь запустить напрямую). Если запускать этот файл двойным кликом в операционной системе — всё отлично работает. Если вызывать его из 1С на клиенте с помощью метода ЗапуститьПриложение — тоже всё успешно выполняется. Но стоит только перенести выполнение кода на сервер 1С, как скрипт перестает отрабатывать, зависает или выдает неочевидные ошибки.
Давайте подробно проанализируем причины такого поведения и рассмотрим надежные способы решения этой задачи, чтобы ваш код безотказно работал на сервере 1С.
Основная проблема кроется в архитектуре работы серверной платформы 1С. Когда вы запускаете 1С на клиенте (на своем рабочем компьютере), программа работает под вашей текущей учетной записью Windows. У этой учетной записи есть доступ к вашим личным папкам, переменным окружения и профилю пользователя.
Однако служба "Агент сервера 1С:Предприятия" по умолчанию запускается под специальной системной учетной записью, как правило, это USR1CV8. И здесь возникают две главные трудности:
AppData\Local\Programs\Python). Пользователь USR1CV8 физически не имеет доступа к этой директории. То же самое касается библиотек, установленных через pip.PATH для пользователя службы может не содержать путь к python.exe, из-за чего вызов простой команды python script.py завершается ошибкой "не удается найти указанный файл".В нашем случае разработчик пытался сделать импорт библиотеки shapefile (установленной через пакет pyshp). На сервере код зависал или падал, потому что библиотека была установлена локально для профиля разработчика.
Рассмотрим по шагам самое быстрое решение, которое помогло автору проблемы. Суть в том, чтобы сделать интерпретатор и его библиотеки доступными для всех пользователей операционной системы, включая системные службы.
C:\Program Files\Python или C:\Program Files\Python39.pip install pyshp. Библиотека запишется в папку C:\Program Files\Python\Lib\site-packages.PATH, работающий сервер 1С об этом не узнает до перезапуска.После этих шагов вызов интерпретатора через метод ЗапуститьПриложение на сервере должен завершаться успешно:
КомандаЗапуска = """C:\Program Files\Python39\python.exe"" D:\Projects\Python\ForCreatedShp.py";
ЗапуститьПриложение(КомандаЗапуска);
Хотя глобальная установка решает проблему, в мире Python это считается плохим тоном. Разные скрипты могут требовать разных версий одних и тех же библиотек. Посмотрим на более правильный архитектурный подход — использование виртуальных окружений.
D:\Projects\Python\ и убедитесь, что у пользователя USR1CV8 есть права на чтение и выполнение файлов в этой папке.python -m venv D:\Projects\Python\venvpyshp конкретно в него.Пример вызова из 1С:
ПутьКPython = "D:\Projects\Python\venv\Scripts\python.exe";
ПутьКСкрипту = "D:\Projects\Python\ForCreatedShp.py";
ЗапуститьПриложение(ПутьКPython + " " + ПутьКСкрипту);
Этот подход гарантирует стабильность: переустановка глобального Python на сервере никак не сломает ваш рабочий скрипт.
Разберем ситуацию, когда скрипт всё равно не работает, и нам нужно понять почему. Использование ЗапуститьПриложение не позволяет нам прочитать текст системной ошибки (например, если 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С:
HTTPСоединение обычным POST-запросом на localhost:8080/create_shape.Этот подход полностью и навсегда снимает проблемы с правами USR1CV8 на файловую систему, путями к интерпретатору и переменными окружения.