Как реализовать параллельное подключение к 1С 7.7 из 1С 8.3 через OLE/COM на сервере?

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

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

Анализ исходной ситуации и программного кода

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


Функция ПодключитьБазу77(ВнешняяБаза) Экспорт
    Попытка
        // Создаем COM-объект. Используем версионно-независимый ключ.
        БазаОЛЕ = Новый COMОбъект("V1CEnterprise.Application");
    Исключение
        Возврат "Ошибка создания объекта: " + ОписаниеОшибки();
    КонецПопытки;

    Путь = ВнешняяБаза.Путь;
    Пользователь = ВнешняяБаза.Пользователь;
    Пароль = ВнешняяБаза.Пароль;
    
    // Попытка инициализации соединения
    ПараметрыЗапуска = "/D" + Путь + " /n" + Пользователь + " /p" + Пароль;
    Если БазаОЛЕ.Initialize(БазаОЛЕ.RMTrade, ПараметрыЗапуска, "NO_SPLASH_SHOW") Тогда
        Возврат БазаОЛЕ;
    Иначе
        Возврат "Ошибка метода Initialize. Возможно, база занята или недостаточно прав.";
    КонецЕсли; 
КонецФункции

Как мы видим, основная проблема возникает не на этапе Новый COMОбъект, а именно при выполнении метода Initialize. В серверном окружении 1С 7.7 ведет себя капризно, так как она изначально не проектировалась для работы в многопоточном режиме службы, хотя и поддерживает современные механизмы отправки API запросов.

Причина 1: Ограничение Desktop Heap (Куча рабочего стола)

Выясним причину, по которой Initialize возвращает Ложь. 1С 7.7 — это 32-битное приложение, которое даже в режиме OLE пытается инициализировать определенные графические ресурсы. В Windows для сервисов (к которым относится сервер 1С) выделяется отдельный неинтерактивный рабочий стол с очень ограниченным объемом памяти, называемым Desktop Heap.

Когда запускается один экземпляр 7.7, он занимает часть этой памяти. При попытке запуска второго экземпляра памяти под графические объекты не хватает, и ядро 7.7 аварийно завершает инициализацию. Рассмотрим, как это исправить через реестр Windows:

  1. Откройте редактор реестра regedit.
  2. Перейдите к ветке: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SubSystems.
  3. Найдите параметр Windows. Это длинная строка.
  4. В этой строке найдите фрагмент SharedSection=xxxx,yyyy,zzzz.
  5. Третье число (zzzz) отвечает за размер кучи для неинтерактивных сессий. По умолчанию оно может быть 512. Увеличьте его до 1024 или 2048.
  6. Перезагрузите сервер.

Причина 2: Изоляция через COM+ Application

Проанализируем ситуацию, когда сервер 1С 8.3 работает как 64-битный процесс. Напрямую загрузить 32-битную библиотеку 1С 7.7 в адресное пространство 64-битного процесса невозможно. В этом случае Windows использует COM Surrogate (процесс dllhost.exe). Однако стандартный суррогат плохо справляется с параллельностью для 7.7.

Для решения этой задачи создадим собственную «обертку» в службах компонентов:

  1. Запустите dcomcnfg (Службы компонентов).
  2. Перейдите в Компьютеры -> Мой компьютер -> Приложения COM+.
  3. Создайте новое пустое приложение. Назовите его, например, 1C77_Legacy_Bridge.
  4. Укажите тип активации: Серверное приложение.
  5. На вкладке Удостоверение (Identity) обязательно выберите конкретного пользователя (администратора), под которым будет запускаться 1С 7.7. Это решит проблемы с доступом к файловой системе и реестру.
  6. В созданное приложение в раздел Компоненты добавьте библиотеку 1С 7.7 (обычно это dbeng32.dll или регистрация через V1CEnterprise.Application).

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

Причина 3: Конфликты временных файлов и профиля

Разберем еще один важный аспект. 1С 7.7 при запуске создает временные файлы в папке TEMP и обращается к файлу настроек 1cv7.cfg. Если все OLE-сессии запускаются от имени одного пользователя службы usr1cv8, может возникнуть конфликт доступа к файлам (File Lock).

Рекомендация: Убедитесь, что у пользователя 1С 7.7 в конфигураторе не указан конкретный каталог пользователя, либо этот каталог уникален для каждой интеграционной задачи. Также проверьте, что папки Temp системного профиля (например, C:\Windows\ServiceProfiles\NetworkService\AppData\Local\Temp) доступны для записи и не переполнены.

Использование различных ключей ProgID

Проанализируем, какой именно объект мы создаем. В системе могут быть зарегистрированы разные версии 7.7. Вместо универсального V1CEnterprise.Application попробуйте использовать специфичные ключи, чтобы исключить ошибки поиска в реестре:

Пример изменения кода для работы с SQL-версией:


БазаОЛЕ = Новый COMОбъект("V77S.Application");

Альтернативный подход: Очередь запросов

Если манипуляции с DCOM и Desktop Heap кажутся слишком рискованными для рабочего сервера, рассмотрим архитектурное решение проблемы. Вместо прямого OLE-запроса из HTTP-сервиса, можно использовать «промежуточное звено»:

  1. 8.3 записывает задание на получение данных в специальную таблицу (очередь) в SQL или файл.
  2. На сервере постоянно запущен «робот» (отдельный процесс 7.7), который мониторит эту таблицу.
  3. Робот обрабатывает запрос, выгружает результат в JSON или XML и помечает задание как выполненное.
  4. 8.3 считывает готовый результат.

Такой подход медленнее на 1–2 секунды, но он абсолютно стабилен, так как исключает конфликты OLE-инициализации в контексте системных служб. Рассмотрим также вариант использования внешних компонент, таких как 1с++, которые позволяют выполнять прямые SQL-запросы к базе 7.7, минуя механизм OLE. Это самый быстрый способ получения данных, который не требует запуска графического ядра 7.7 вообще.

Заключение

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

  1. Увеличить Desktop Heap в реестре до 2048 КБ.
  2. Настроить COM+ приложение для изоляции процессов OLE.
  3. Использовать версионно-зависимые ProgID (например, V77S.Application).
  4. Очистить временные папки профиля пользователя сервера.
  5. При невозможности настройки — перейти на использование прямых SQL-запросов через ODBC.

Применяя эти методы, вы сможете построить высокопроизводительный «веб-сервер» на базе 1С 8.3, который будет бесперебойно отдавать данные из старых баз 7.7 в современные мобильные приложения или внешние системы.

← На главную