При автоматизации задач 1С с использованием внешних скриптов (VBScript, JavaScript, PowerShell) программисты часто сталкиваются с неприятной особенностью: после выполнения всех операций и вызова команды завершения сеанса, процесс 1cv8.exe продолжает «висеть» в диспетчере задач. Это особенно критично для регламентных заданий, которые запускаются по расписанию: со временем десятки зависших процессов могут полностью исчерпать ресурсы оперативной памяти сервера или рабочей станции.
В этой статье мы подробно разберем причины возникновения этой проблемы и рассмотрим несколько эффективных способов ее решения, основываясь на опыте практикующих разработчиков и особенностях работы COM-технологий.
Проанализируем ситуацию: использование объекта V82.Application (или V83.Application) подразумевает запуск полноценного клиентского приложения. Когда мы вызываем метод connection.Exit(False), система пытается закрыть приложение. Однако процесс может остаться в памяти по нескольким причинам:
1cv8.exe в файловом режиме.Если вам не требуется интерактивное взаимодействие с пользователем (показ форм, диалогов), наиболее правильным решением будет использование объекта 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).
Если использование 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
Метод 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
Если штатные методы 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;
Иногда корень проблемы кроется внутри самой базы 1С. Разберем, что нужно проверить программисту 1С в модуле приложения:
Отказ = Истина при определенных обстоятельствах (например, если не заполнены какие-то реквизиты).Запрашивать подтверждение при закрытии программы.Для надежной работы скриптов автоматизации мы рекомендуем придерживаться следующей стратегии:
V83.COMConnector), если вам не нужен интерфейс 1С.Set Var = Nothing) перед вызовом Exit.On Error Resume Next и Terminate().taskkill для очистки «хвостов» в памяти.Соблюдение этих правил позволит вашим скриптам работать стабильно, не перегружая сервер лишними процессами и обеспечивая бесперебойную работу регламентных задач.