При разработке интеграционных механизмов и систем уведомлений разработчики нередко используют запуск внешних сценариев VBScript (.vbs) через метод платформы ЗапуститьПриложение. Однако при переносе работающего кода из интерактивной сессии (внешняя обработка, консоль кода) в серверный модуль или регламентное задание процесс 1С может зависнуть намертво.
Проанализируем причины такого поведения серверной службы 1С:Предприятия и разберем все способы корректного решения проблемы.
Выясним, почему одна и та же строчка кода успешно отрабатывает в консоли кода у пользователя, но блокирует серверный поток при исполнении на стороне сервера:
ragent.exe и rphost.exe) функционирует в изолированной неинтерактивной сессии Windows. Если запускаемый скрипт, интерпретатор или система пытается отобразить диалоговое окно (например, предупреждение системы безопасности, ошибку выполнения или окно подтверждения), оно физически не выводится на экран. Если для метода 1С включено ожидание завершения, поток уходит в бесконечное ожидание ответа пользователя.\\Имя_сервера\Папка\Mail.vbs операционная система по умолчанию применяет политики безопасности для зоны интрасети или интернета. Это может приводить к скрытому диалогу подтверждения запуска небезопасного файла. Кроме того, учетная запись, под которой запущена служба сервера 1С (например, usr1cv8), может не иметь доступа к сетевому ресурсу..vbs Windows выбирает оконный интерпретатор по умолчанию (wscript.exe), который при любых непредвиденных ситуациях генерирует модальные окна.Самое быстрое исправление, решающее проблему блокировок сетевых зон безопасности, — разместить скрипт непосредственно на диске того сервера, где работает служба 1С, и указать прямой локальный путь.
Посмотрим на пример вызова:
// Вместо сетевого пути вида "\\ServerName\Scripts\Mail.vbs"
// используем локальный путь на сервере приложений 1С:
СтрокаКоманды = "C:\Scripts\Mail.vbs";
ЗапуститьПриложение(СтрокаКоманды, "C:\Scripts\", Истина);
Важно: убедитесь, что у учетной записи пользователя Windows, от имени которой запущена служба 1C:Enterprise Server, назначены полные права на чтение и исполнение файлов в выбранном каталоге.
Для гарантированного исключения любых зависаний в фоновых процессах рекомендуется запускать скрипт не напрямую через расширение файла, а через консольный интерпретатор cscript.exe, передавая ему специальные параметры подавления диалогов и таймаута.
Разберем параметры запуска cscript.exe:
//B (Batch mode) — пакетный режим, полностью отключающий вывод предупреждений, диалоговых окон и сообщений об ошибках в виде окон.//Nologo — скрывает стартовый заголовок Windows Script Host.//T:секунды — жестко ограничивает время выполнения скрипта (таймаут). Если скрипт зависнет из-за сетевых проблем при отправке почты, операционная система принудительно завершит процесс по истечении указанного времени.Рассмотрим пример кода на стороне сервера 1С:
ПутьКИнтерпретатору = "cscript.exe";
ПараметрыЗапуска = "//B //Nologo //T:30 ""C:\Scripts\Mail.vbs""";
КоманднаяСтрока = ПутьКИнтерпретатору + " " + ПараметрыЗапуска;
РабочийКаталог = "C:\Scripts";
КодВозврата = 0;
ЗапуститьПриложение(КоманднаяСтрока, РабочийКаталог, Истина, КодВозврата);
Если КодВозврата <> 0 Тогда
ЗаписьЖурналаРегистрации("ОтправкаПочты", УровеньЖурналаРегистрации.Ошибка,,, "Скрипт завершился с кодом: " + КодВозврата);
КонецЕсли;
Если скрипт VBScript используется исключительно для формирования и отправки почты через CreateObject("CDO.Message"), наиболее надежным и производительным решением будет отказ от внешних файлов .vbs и запуск через встроенный в 1С механизм работы с COM-объектами.
Посмотрим, как перенести почтовую отправку непосредственно в код 1С на сервере Windows:
Письмо = Новый COMОбъект("CDO.Message");
Конфигурация = Новый COMОбъект("CDO.Configuration");
Схема = "http://schemas.microsoft.com/cdo/configuration/";
Поля = Конфигурация.Fields;
// Настройка параметров подключения к SMTP-серверу
Поля.Item(Схема + "sendusing").Value = 2; // cdoSendUsingPort
Поля.Item(Схема + "smtpserver").Value = "smtp.company.ru";
Поля.Item(Схема + "smtpserverport").Value = 25;
Поля.Item(Схема + "smtpauthenticate").Value = 1; // cdoBasic
Поля.Item(Схема + "sendusername").Value = "robot@company.ru";
Поля.Item(Схема + "sendpassword").Value = "Pass123";
Поля.Item(Схема + "smtpusessl").Value = Ложь;
Поля.Update();
Письмо.Configuration = Конфигурация;
Письмо.From = "robot@company.ru";
Письмо.To = "manager@company.ru";
Письмо.Subject = "Уведомление из 1С";
Письмо.TextBody = "Текст сообщения сформирован сервером 1С.";
Попытка
Письмо.Send();
Исключение
ИнформацияОбОшибке = ОписаниеОшибки();
ЗаписьЖурналаРегистрации("ОтправкаПочты", УровеньЖурналаРегистрации.Ошибка,,, ИнформацияОбОшибке);
КонецПопытки;
Такой подход полностью устраняет риски зависания подсистемы запуска процессов, не требует создания временных файлов на диске и позволяет перехватывать любые сетевые исключения штатными средствами языка 1С через конструкцию Попытка ... Исключение.