При организации интеграции между 1С:Предприятие 8.3 и устаревшими базами 1С:Предприятие 7.7 разработчики часто используют технологию OLE/COM Automation. Типовой сценарий предполагает запуск регламентного фонового задания на сервере «восьмерки», которое поочередно подключается к базам «семерки» через метод Initialize и считывает необходимые данные. Однако на практике часто возникает ситуация: на клиенте код отрабатывает без нареканий, а при выполнении в фоновом задании на сервере вызов V7.Initialize падает с ошибкой.
Проанализируем базовый пример кода подключения, который обычно вызывает исключение:
Попытка
V7 = Новый COMОбъект("V1CEnterprise.Application");
Исключение
V7 = Новый COMОбъект("v77s.Application");
КонецПопытки;
ПараметрыПодключения = "/D""" + СокрЛП(ПутьКБазе) + """";
Если ЗначениеЗаполнено(Пользователь) Тогда
ПараметрыПодключения = ПараметрыПодключения + " /N""" + СокрЛП(Пользователь) + """";
КонецЕсли;
Если ЗначениеЗаполнено(Пароль) Тогда
ПараметрыПодключения = ПараметрыПодключения + " /P""" + СокрЛП(Пароль) + """";
КонецЕсли;
Попытка
Результат = V7.Initialize(V7.RMTrade, ПараметрыПодключения, "NO_SPLASH_SHOW");
Если Результат = 0 Тогда
ВызватьИсключение "Не удалось инициализировать систему 1С 7.7";
КонецЕсли;
Исключение
ЗаписьЖурналаРегистрации("Ошибка OLE 7.7", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
КонецПопытки;
Разберем детально, почему этот механизм дает сбои в серверном контексте, и рассмотрим по шагам все способы устранения проблемы.
Сервер приложений 1С 8.3 (процесс rphost.exe) функционирует как системная служба Windows в изолированной Session 0. В этой сессии полностью отсутствует интерактивный рабочий стол. Если при старте базы 1С 7.7 в глобальном модуле в процедуре ПриНачалеРаботыСистемы() вызываются функции Предупреждение(), Вопрос(), открываются диалоговые формы обработок (например, проверка обновлений, регламентные напоминания или пересчет итогов), процесс 1cv7.exe / 1cv7s.exe зависает в ожидании нажатия кнопки пользователем либо аварийно завершается.
Выясним, как это исправить:
ПриНачалеРаботыСистемы().
Процедура ПриНачалеРаботыСистемы()
// Проверяем, запущена ли система как OLE-сервер или регламентный процесс
Если МонопольныйРежим() = 0 Тогда
// Отключаем открытие интерактивных форм для фонового пользователя
Если ИмяПользователя() <> "COM_User" Тогда
// Интерактивные предупреждения и открытие стартовых обработок
ОткрытьФорму("Обработка.Напоминания");
КонецЕсли;
КонецЕсли;
КонецПроцедуры
При инициализации 32-разрядных OLE-серверов под учетными записями системных служб операционная система Windows обращается к специальным каталогам рабочего стола. Если они отсутствуют, метод Initialize возвращает ошибку инициализации приложения.
Выполним следующие системные настройки на сервере:
C:\Windows\System32\config\systemprofile\DesktopC:\Windows\SysWOW64\config\systemprofile\Desktopusr1cv8).Для неинтерактивных сессий служб Windows по умолчанию выделяется крайне малый объем памяти на отрисовку оконных дескрипторов (Desktop Heap). При запуске OLE-экземпляров 1С 7.7 лимит исчерпывается, что приводит к сбою в библиотеке Frame.dll.
Увеличим лимит памяти через системный реестр Windows:
regedit.HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems.Windows и найдем фрагмент SharedSection=xxxx,yyyy,zzzz.zzzz), отвечающее за неинтерактивные службы, до 2048 или 8192.Платформа 1С 7.7 существует исключительно в 32-разрядной архитектуре. Если служба сервера 1С 8.3 установлена как 64-битное приложение, прямой вызов 32-битного COM-объекта завершится ошибкой. Для корректной трансляции вызовов настроим суррогатное приложение COM+:
dcomcnfg.exe).1C77_COM) и тип активации Серверное приложение.V77.Application, V77S.Application и V1CEnterprise.Application.При циклическом опросе нескольких информационных баз в одном сеансе критически важно следить за синтаксисом параметров и явной очисткой COM-объектов. Проверим правильность формирования параметров и освобождения памяти:
OrdNoChk.prm в каталог BIN платформы 7.7 или непосредственно в каталог базы данных.1cv7s.exe:
// Очистка объекта и освобождение COM-соединения
V7 = Неопределено;
СборкаМусора();
Если специфика серверной операционной системы или ограничения безопасности не позволяют стабильно запускать OLE 7.7 в службах Windows, применим альтернативные подходы: