Как устранить зависание процесса 1С при завершении работы VBS-скрипта?

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

При автоматизации задач 1С с использованием внешних скриптов (VBScript, JavaScript, PowerShell) программисты часто сталкиваются с неприятной особенностью: после выполнения всех операций и вызова команды завершения сеанса, процесс 1cv8.exe продолжает «висеть» в диспетчере задач. Это особенно критично для регламентных заданий, которые запускаются по расписанию: со временем десятки зависших процессов могут полностью исчерпать ресурсы оперативной памяти сервера или рабочей станции.

В этой статье мы подробно разберем причины возникновения этой проблемы и рассмотрим несколько эффективных способов ее решения, основываясь на опыте практикующих разработчиков и особенностях работы COM-технологий.

Причина зависания: почему метод Exit не всегда работает?

Проанализируем ситуацию: использование объекта V82.Application (или V83.Application) подразумевает запуск полноценного клиентского приложения. Когда мы вызываем метод connection.Exit(False), система пытается закрыть приложение. Однако процесс может остаться в памяти по нескольким причинам:

  1. Счетчик ссылок COM: Если в вашем скрипте осталась хотя бы одна переменная, которая ссылается на объект внутри 1С (например, на справочник, документ или даже системную информацию), COM-механизм Windows не позволит процессу завершиться, пока все ссылки не будут уничтожены.
  2. Модальные окна: В настройках пользователя 1С может быть включена опция «Запрашивать подтверждение при закрытии». В этом случае 1С создает невидимое окно вопроса, которое блокирует закрытие процесса, ожидая ответа пользователя.
  3. Особенности платформы: Некоторые релизы платформы (например, обсуждаемый 8.2.15.289) имеют внутренние ошибки в реализации механизма OLE-автоматизации, что препятствует корректной выгрузке 1cv8.exe в файловом режиме.

Решение 1: Использование COMConnector вместо Application

Если вам не требуется интерактивное взаимодействие с пользователем (показ форм, диалогов), наиболее правильным решением будет использование объекта COMConnector. Он работает быстрее, потребляет меньше памяти и более предсказуемо завершает сеанс.

Рассмотрим пример кода на VBScript для подключения через COMConnector:


Dim ComConnector
Dim connection

Set ComConnector = CreateObject("V82.COMConnector")
' Для платформы 8.3 используйте V83.COMConnector

' Строка подключения для файловой базы
Set connection = ComConnector.Connect("File=""C:\Base1C"";Usr=""Admin"";Pwd=""123"";")

' Выполняем необходимые действия, например, запись в журнал
connection.WriteLogEvent "Регламентное задание", 2, , , "Обмен завершен"

' Важно: Сначала зануляем объект соединения, затем сам коннектор
Set connection = Nothing
Set ComConnector = Nothing

Обратите внимание, что у объекта COMConnector нет метода Exit. Сессия закрывается автоматически, как только вы присваиваете переменной значение Nothing (в VBScript) или null (в JScript).

Решение 2: Тотальная очистка ссылок на объекты

Если использование Application неизбежно, необходимо убедиться, что ни одна переменная в скрипте не удерживает ссылку на внутренние объекты 1С. Разберем по шагам: если вы создали объект справочника или выборку, их нужно уничтожить ДО закрытия основного соединения.

Посмотрим на пример правильной последовательности действий:


Set connection = CreateObject("V82.Application")
connection.Connect("File=""C:\Base"";Usr=""Admin"";")

Set СправочникНоменклатура = connection.Catalogs.Номенклатура.CreateItem()
СправочникНоменклатура.Наименование = "Тестовый товар"
СправочникНоменклатура.Write()

' ОШИБКА: Если здесь вызвать connection.Exit, процесс зависнет, 
' так как переменная СправочникНоменклатура все еще удерживает объект.

' ПРАВИЛЬНО:
Set СправочникНоменклатура = Nothing 
connection.Exit(False)
Set connection = Nothing

Решение 3: Метод Terminate и подавление ошибок RPC

Метод connection.Terminate() завершает процесс 1С принудительно. Однако он часто вызывает системную ошибку 800706BE («Сбой при удаленном вызове процедуры»), так как скрипт теряет связь с объектом в момент его уничтожения. Выясним, как обойти эту «неприятность» с помощью обработки ошибок.

Рассмотрим пример реализации:


On Error Resume Next ' Включаем игнорирование ошибок
connection.Terminate() 
If Err.Number <> 0 Then
    ' Ошибку 800706BE просто игнорируем, так как цель достигнута — процесс убит
    Err.Clear
End If
On Error GoTo 0 ' Возвращаем стандартный режим обработки ошибок
Set connection = Nothing

Решение 4: Принудительное завершение через WMI (Taskkill)

Если штатные методы 1С не помогают (что часто бывает в файловом режиме на Windows 7/10), можно прибегнуть к системным средствам. Мы можем найти ID процесса 1С, который был запущен нашим скриптом, и «кильнуть» его средствами ОС.

Проанализируем ситуацию: чтобы не убить лишние процессы 1С (если открыты другие базы), можно использовать проверку по времени запуска или через объект WScript.Shell.


Dim oShell
Set oShell = CreateObject("WScript.Shell")

' Вариант 1: Жесткое завершение всех процессов 1cv8.exe
' Используйте с осторожностью!
oShell.Run "taskkill /im 1cv8.exe /f", 0, True

' Вариант 2: Более изящный способ через JavaScript (сообщение 24 в теме)
' В JScript зануление объектов работает через null:
' connection = null;
' ComConnector = null;

Решение 5: Проверка конфигурации 1С

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

Подводим итоги

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

  1. Всегда отдавайте предпочтение COMConnector (V83.COMConnector), если вам не нужен интерфейс 1С.
  2. Если используете Application, всегда явно обнуляйте ВСЕ созданные переменные (Set Var = Nothing) перед вызовом Exit.
  3. Для гарантированного закрытия процесса используйте связку On Error Resume Next и Terminate().
  4. Если база файловая и платформа старая (8.2), будьте готовы к использованию системной команды taskkill для очистки «хвостов» в памяти.

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

← На главную