При интеграции современных систем на базе 1С:Предприятие 8.3 с наследуемыми базами 1С 7.7 разработчики часто сталкиваются с труднопреодолимым препятствием. Если сервер 1С 8 работает в 64-битном режиме, попытка инициализации COM-объекта «семерки» на стороне сервера заканчивается ошибкой Initialize: Неизвестная ошибка. При этом тот же самый код прекрасно отрабатывает в файловой версии или при запуске на клиенте.
В данной статье мы подробно разберем, почему возникает эта проблема, проанализируем внутренние механизмы взаимодействия процессов разной разрядности и рассмотрим пошаговые инструкции по настройке стабильного подключения.
Рассмотрим типичный фрагмент кода, который используется для подключения. Обычно процедура выполняется в контексте &НаСервереБезКонтекста, так как именно серверная часть отвечает за регламентные задания и фоновую обработку данных.
&НаСервереБезКонтекста
Процедура ПодключениеСервер77(СтруктураПараметров)
ПутьКБазе = "D:\Base1C\Base1\";
Пользователь = "Робот";
Пароль = "1234";
Попытка
База77 = Новый COMОбъект("V1CEnterprise.Application");
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
Попытка
СтрокаПодключения = "/D""" + СокрЛП(ПутьКБазе) + """ /N""" + СокрЛП(Пользователь) + """ /P""" + СокрЛП(Пароль) + """";
// Именно здесь возникает ошибка "Неизвестная ошибка"
РезультатПодключения = База77.Initialize(База77.RMTrade, СтрокаПодключения, "NO_SPLASH_SHOW");
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
КонецПроцедуры
Проанализируем ситуацию: объект V1CEnterprise.Application создается успешно, что говорит о том, что COM-сервер зарегистрирован в системе. Однако метод Initialize, который должен запустить ядро 1С 7.7, инициализировать графическую оболочку (пусть и в невидимом режиме) и подключить таблицы данных, выбрасывает исключение. Основная причина кроется в архитектурном конфликте: 64-битный процесс rphost.exe не может напрямую взаимодействовать с 32-битными динамическими библиотеками 1С 7.7.
Процесс сервера 1С 8 (x64) ожидает, что вызываемый COM-объект будет иметь ту же разрядность. Но 1С 7.7 существует только в 32-битном исполнении. Когда мы вызываем Initialize, система пытается загрузить компоненты 1С 7.7 в адресное пространство 64-битного процесса rphost, что технически невозможно в рамках архитектуры Windows без специальной прослойки.
Решение через настройку COM+:
Для обхода этого ограничения нам необходимо заставить 1С 7.7 работать в собственном отдельном 32-битном процессе, который будет выступать посредником. Это делается через «Службы компонентов» Windows.
dcomcnfg).1C77_Bridge. Установим способ активации — «Серверное приложение».USR1CV8). Крайне важно, чтобы у этого пользователя были права на папку с базой 1С 7.7.comcntr.dll или регистрация по ID объекта V1CEnterprise.Application).После этой настройки система при вызове Новый COMОбъект будет запускать отдельный процесс dllhost.exe (32-битный), который успешно инициализирует 1С 7.7 и передаст данные обратно в 64-битный rphost.
Службы Windows (включая сервер 1С) работают в так называемой «Сессии 0». В этой сессии нет полноценного рабочего стола, графической подсистемы и принтеров. 1С 7.7 при инициализации через OLE всё равно пытается обратиться к некоторым элементам интерфейса и, что критично, ищет принтер по умолчанию.
Если в профиле пользователя USR1CV8 не настроен принтер или не созданы временные папки, Initialize вернет ошибку. Выясним, как это исправить:
USR1CV8.C:\Windows\Temp и в папку профиля %APPDATA%.На 64-битных операционных системах ветки реестра для 32-битных программ дублируются в разделе HKEY_CLASSES_ROOT\Wow6432Node. Иногда автоматическая регистрация 1С 7.7 не прописывает ключи там, где их ожидает увидеть сервер 1С 8.
Проанализируем реестр. Попробуем использовать более специфичные программные идентификаторы (ProgID) вместо универсального V1CEnterprise.Application. В зависимости от версии 1С 7.7, попробуем заменить строку создания объекта на следующие варианты:
База77 = Новый COMОбъект("V77.Application"); — для сетевой версии.База77 = Новый COMОбъект("V77S.Application"); — для SQL-версии.База77 = Новый COMОбъект("V77M.Application"); — для локальной версии.Если настройка COM+ и манипуляции с реестром не помогают, рассмотрим более надежный архитектурный подход. Мы можем создать промежуточную файловую базу 1С 8 (x86).
Логика работы будет следующей: 1. Основной сервер 1С 8 (x64) запускает фоновое задание. 2. Это задание через COM-соединение подключается к маленькой 32-битной файловой базе 1С 8. 3. Уже эта файловая база (будучи 32-битным процессом) подключается к 1С 7.7 по OLE без всяких конфликтов разрядности. 4. Данные передаются транзитом: 7.7 -> 8.3 (x86) -> 8.3 (x64).
Этот метод кажется более сложным, но он избавляет от проблем с системными правами и обновлениями Windows, которые могут «сбросить» настройки COM+.
Если задача заключается только в получении данных (чтении), а не в выполнении логики внутри 1С 7.7 (проведение документов, расчет итогов), проанализируем возможность прямого чтения таблиц. Если база 1С 7.7 файловая, она хранит данные в формате DBF.
Мы можем использовать объект ADOConnection для прямого выполнения SQL-запросов к DBF-файлам. Этот метод работает значительно быстрее, чем OLE, и полностью игнорирует проблемы разрядности 1С 7.7, так как нам не нужно запускать само приложение V1CEnterprise.
Пример инициализации ADO для работы с 1С 7.7:
Connection = Новый COMОбъект("ADODB.Connection");
ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + ПутьКБазе + ";Extended Properties=dBASE IV;";
Connection.Open(ConnectionString);
// Далее выполняем запросы к файлам типа SC123.DBF (справочники) или DH456.DBF (документы)
Подведем итоги: для успешного подключения из 64-битной 1С 8 к 1С 7.7 по OLE необходимо либо настроить «мост» через COM+, либо обеспечить полное окружение пользователя в Session 0, либо использовать 32-битные промежуточные приложения. Каждый из этих способов позволяет обойти фундаментальное ограничение операционной системы на смешивание кода разной разрядности в одном процессе.