Почему зависает сеанс 1С при запуске через планировщик задач Windows и как это исправить?

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

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

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

Анализ причин зависания сеанса

Выясним причину такого поведения системы. Разница между интерактивным запуском пользователем и выполнением через Планировщик задач кроется в контексте безопасности операционной системы и поведении самой платформы 1С:

  1. Запуск в изолированной «Сессии 0» (Session 0 Isolation): Если в свойствах задачи планировщика включена опция «Выполнять вне зависимости от того, вошел ли пользователь в систему», процесс стартует в неинтерактивной сессии без графического десктопа. Любые обращения к графическому интерфейсу, вызовы окон сообщений или неявные обращения к оконной подсистеме приводят к блокировке потока.
  2. Механизм защиты от опасных действий: Начиная с версий платформы 8.3.8, при попытке открыть внешнюю обработку через параметр командной строки /Execute система безопасности выводит модальное окно с предупреждением об открытии потенциально опасного файла. В неинтерактивной сессии это окно не отображается на экране, и толстый клиент бесконечно ждет нажатия кнопки подтверждения.
  3. Ошибки инициализации и закрытия формы: Если в модуле формы внешней обработки алгоритм запускается непосредственно в обработчике ПриОткрытии, а в конце вызываются методы ЭтаФорма.Закрыть() и ЗавершитьРаботуСистемы(), происходит коллизия: окно еще не успело завершить процедуру отрисовки и инициализации, а его уже пытаются принудительно уничтожить.
  4. Диалоговые окна платформы: При старте клиента могут возникать служебные диалоги (о несоответствии версий, необходимости обновления метаданных или информационные сообщения), требующие реакции пользователя.

Способ 1. Корректировка параметров командной строки и отключение защиты

Проанализируем базовый вызов через командную строку. Исходная строка запуска выглядит следующим образом:


"C:\Program Files (x86)\1cv8\8.3.8.1747\bin\1cv8.exe" Enterprise /S"Server\Base" /N"User" /P"Pass" /Execute"E:\1C\Test.epf"

Для предотвращения зависаний выполним следующие настройки:

  1. Отключим защиту от опасных действий для служебного пользователя: В конфигураторе откроем список пользователей (меню «Администрирование» — «Пользователи»), выберем пользователя, под которым выполняется запуск, и снимем флажок «Защита от опасных действий». Либо в конфигурационном файле conf.cfg платформы пропишем директиву DisableUnsafeActionProtection=.*.
  2. Добавим подавление диалогов и запись лога: Обязательно передадим ключи /DisableStartupMessages, /DisableStartupDialogs, /ClearCache, а также укажем вывод системных сообщений в файл через /Out, чтобы можно было локализовать ошибки старта.
  3. Проверим пути: Если файл обработки расположен на диске E:, убедимся, что это локальный физический накопитель сервера. Если это сетевой диск, обращение к нему из планировщика завершится ошибкой, так как сопоставленные сетевые буквы не монтируются в фоновых сессиях. В таком случае следует использовать UNC-путь вида \\server\share\Test.epf.

Посмотрим на пример правильного формирования батника:


@echo off
chcp 1251 >nul
"C:\Program Files (x86)\1cv8\8.3.8.1747\bin\1cv8.exe" Enterprise /S"Server\Base" /N"User" /P"Pass" /DisableStartupMessages /DisableStartupDialogs /ClearCache /Execute "E:\1C\Test.epf" /Out "E:\1C\log.txt" -NoTruncate

Способ 2. Исправление программного кода внешней обработки

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


Граница = Последовательности.ПартионныйУчет.ПолучитьГраницу(); 
Запрос = Новый Запрос; 
Запрос.УстановитьПараметр("Граница", Граница); 
Запрос.УстановитьПараметр("Дата", Граница.Дата); 
Запрос.Текст = 
    "ВЫБРАТЬ 
    |	ПартионныйУчет.Регистратор, 
    |	ПартионныйУчет.Период КАК Период, 
    |	ПартионныйУчет.Регистратор.Проведен КАК Проведен 
    |ИЗ 
    |	Последовательность.ПартионныйУчет КАК ПартионныйУчет 
    |ГДЕ 
    |	ПартионныйУчет.МоментВремени > &Граница 
    |	И ПартионныйУчет.Период >= &Дата 
    |УПОРЯДОЧИТЬ ПО 
    |	Период, 
    |	ПартионныйУчет.МоментВремени"; 

Выборка = Запрос.Выполнить().Выбрать(); 
Пока Выборка.Следующий() Цикл 
    Если НЕ Выборка.Проведен Тогда 
        Выборка.Регистратор.ПолучитьОбъект().ПринадлежностьПоследовательностям.ПартионныйУчет.Записать(); 
        Продолжить; 
    КонецЕсли; 
    
    Попытка 
        Выборка.Регистратор.ПолучитьОбъект().Записать(РежимЗаписиДокумента.Проведение); 
    Исключение 
        Прервать; 
    КонецПопытки; 
КонецЦикла; 

ПрекратитьРаботуСистемы(Ложь);

Обратим внимание на критически важные изменения:

  1. Исключение интерактивных методов: Конструкции Состояние(...) и ОбработкаПрерыванияПользователя; обращаются к оконной очереди Windows. В фоновом режиме планировщика они вызывают сбои или подвисания, поэтому их необходимо полностью исключить.
  2. Корректное закрытие сеанса: Метод ЗавершитьРаботуСистемы(Ложь, Ложь) производит мягкий опрос модулей и открытых окон на возможность выхода, из-за чего сеанс может застрять. Для фоновых скриптов используем метод ПрекратитьРаботуСистемы(Ложь), который безусловно прерывает выполнение платформы.
  3. Использование обработчика ожидания: Не запускаем тяжелый алгоритм в процедуре ПриОткрытии(). Вместо этого подключаем отложенный вызов, давая форме инициализироваться:

Процедура ПриОткрытии()
    ПодключитьОбработчикОжидания("ВыполнитьИЗакрыть", 0.1, Истина);
КонецПроцедуры

Процедура ВыполнитьИЗакрыть()
    // Основной алгоритм проведения
    // ...
    ПрекратитьРаботуСистемы(Ложь);
КонецПроцедуры

Способ 3. Передача параметра запуска вместо использования внешнего файла

Чтобы полностью обойти механизмы защиты от опасных действий и исключить проблемы с чтением внешних файлов .epf, применим запуск с параметром командной строки /C.

Разберем по шагам, как это реализовать:

  1. В командной строке запуска убираем параметр /Execute и добавляем параметр /C "ВосстановитьПоследовательность":
    
    "C:\Program Files (x86)\1cv8\8.3.8.1747\bin\1cv8.exe" Enterprise /S"Server\Base" /N"User" /P"Pass" /DisableStartupMessages /DisableStartupDialogs /C "ВосстановитьПоследовательность"
    
  2. В конфигураторе открываем модуль обычного приложения (или модуль управляемого приложения) и находим процедуру ПриНачалеРаботыСистемы().
  3. Добавляем проверку значения глобальной функции ПараметрЗапуска:
    
    Если ПараметрЗапуска = "ВосстановитьПоследовательность" Тогда
        // Вызываем процедуру проведения из общего модуля
        МойОбщийМодуль.ВыполнитьВосстановлениеПоследовательности();
        ПрекратитьРаботуСистемы(Ложь);
    КонецЕсли;
    

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

Способ 4. Запуск через Windows Script Host (VBScript)

Если требуется контролировать возврат кода ошибки в операционную систему или обойти проблемы планировщика при прямом вызове .bat, используем запуск через VBScript-обертку с объектом WScript.Shell:


Dim WShShell, Command, ReCode
Set WShShell = WScript.CreateObject("WScript.Shell")

Command = """C:\Program Files (x86)\1cv8\8.3.8.1747\bin\1cv8.exe"" Enterprise /S""Server\Base"" /N""User"" /P""Pass"" /DisableStartupMessages /DisableStartupDialogs /Execute""E:\1C\Test.epf"""

' Параметр 0 скрывает окно, True заставляет скрипт ожидать завершения процесса
ReCode = WShShell.Run(Command, 0, True)

Set WShShell = Nothing

Сохраняем скрипт с расширением .vbs. В Планировщике задач Windows в поле «Программа или сценарий» указываем wscript.exe, а в поле аргументов передаем полный путь к нашему скрипту. В параметрах действия также обязательно заполняем поле «Рабочая папка» (Start in), указав каталог расположения скрипта, что предотвратит ошибки поиска зависимостей в системном каталоге System32.

← На главную