В организации, где я сейчас работаю, для обмена данными между базами 1С широко используется механизм COM. Пока все рабочие базы работали на одном сервере, проблем с этой технологией не было. Организация растет, часть баз уехала на другой сервер, и, когда типовые конфигурации потребовали срочного обновления платформы, на одном из серверов установили сервер приложений одной из последних версий. По некоторым технологическим причинам быстро обновить платформу на втором сервере не представлялось возможным, и интеграция между базами расположенными на разных серверах встала.
Пришлось искать решение. Я имею представление о принципах работы технологии COM (безотносительно к 1С) и посчитал, что есть шанс решить проблему.
До тех пор я «знал», что нельзя заставить COM работать с разными версиями платформы, и не удосужился проверить эту информацию. Статьи на инфостарте нашел уже в ходе своих экспериментов, когда разбирался с ошибками. Тем не менее, решил написать статью с пошаговым руководством, позволяющим избежать все известные мне ошибки.
В ходе эксперимента возникали ошибки. При поиске решения этих ошибок наткнулся на хорошую статью «Параллельное использование нескольких версий COM control (несколько версий платформ)»; и сама статья и комментарии к ней мне очень помогли, но всех проблем решить не смогли.
Эксперименты проводились на виртуальной машине с установленной Windows Server 2012 R2 Standard (англоязычная). Сервер приложений не ставил. Экспериментировал с 32-х разрядной клиентской частью 1С. Для экспериментов написал простую обработку, которая позволяет задавать и сохранять в настройках параметры нескольких COM-подключений, с их помощью подключаться к базам и выполнять произвольный код для проверки корректности подключения. Обработка позволяет выбрать где будет создаваться подключение: на клиенте или на сервере. Обработку прикладываю.
Итак, вот что у меня получилось.
Чтобы не запутаться, приложения буду называть «Приложение1» и «Приложение2», компоненты «Компонент1» и «Компонент2» (само собой их может быть больше). Приложение1 и Компонент1 будут использоваться для подключения к базам на платформе 8.3.12.1595, а Приложение2 и Компонент2 – для 8.3.17.1851.
Порядок действий:
1. В проводнике правой кнопкой мыши по This PC -> Manage. Откроется окно «Server manager. Dashboard».
2. В правом верхнем углу этого окна Tools - > Component services. Откроется соответствующее окно.
3. В дереве левой части окна разворачиваем Console Root -> Component Sarvices -> Computers -> My Computer -> COM+ Applications.
4. Создание приложений.
a. В контекстном меню COM+ Applications в дереве -> New -> Application. Откроется мастер.
b. В окне приветствия жмем Next.
c. Выбираем «Create an empty application».
d. Вводим имя приложения для первого соединения COM. Я в имени использовал номер версии платформы.
e. Жмем Next, и на следующем шаге указываем, пользователя, от имени которого будет работать компонент (я использовал первый вариант, т.к. для эксперимента это не важно).
f. Жмем Next, и следующий шаг позволяет добавить роли, позволяющие работать с этим компонентом. Тут я ничего делать не стал.
g. Жмем Next, и можем в каждую из ролей предыдущего шага добавить конкретных пользователей. Тут также оставил все без изменений.
h. Жмем Next, затем Finish, и у нас есть Приложение1.
i. Аналогично создаем Приложение2.
j. Наше дерево в левой части окна выглядит примерно вот так:
5. Создаем компоненты.
a. Для Приложения1 вызываем контекстное меню для раздела Components –> New -> Component. Откроется мастер установки компонентов.
b. На странице приветствия нажимаем Next, и на следующем шаге выбираем «Install new component(s)».
c. Откроется диалог выбора файла, в котором мы указываем путь к файлу comcntr.dll соответствующей версии.
d. Жмем Next, затем Finish, и у нас появляется новый компонент с названием по умолчанию.
e. Во многих статьях рекомендуют открыть Properties этого компонента и правильно установить настройки безопасности. У меня работает и так, поэтому не буду ничего делать.
f. Жмем правой кнопкой мыши по этому компоненту и в контекстном меню выбираем «Alias…». Откроется инструмент, позволяющий создать копию этого компонента с новыми ProgID и CLSID.
g. В открывшемся окне указываем название нового компонента (я использовал в названии часть номера релиза платформы). Список в левой части окна ("Please select a destination") показывает, в каком приложении будет располагаться наша копия, проверяем, что она остается в Приложении1 и жмем OK.
У нас есть Компонент1.
h. Создаем новый компонент повторяя шаги f и g еще раз, но в названии используем номер другого релиза платформы и в левой части окна указываем, что вторая копия будет располагаться в Приложении2. У нас есть и Компонент2.
i. Структура наших приложений и компонентов теперь выглядит так:
j. Осталась небольшая проблема: все наши компоненты ссылаются на одну и ту-же dll. Для её решения вызываем контекстное меню Компонент2, открываем Properties и копируем CLSID.
k. Запускаем regedit и ищем в дереве узел соответствующий CLSID из предыдущего пункта и содержащий в себе подузел InprocServer32.
l. Путь указанный в значении (Default) меняем на путь к comcntr.dll версии, соответствующей Компонент2.
m. Закрываем regedit.
6. Можем проверить COM-соединения с помощью приложенной обработки.
Обработка для проверки.
Интерфейс обработки прост. По нажатии кнопки «Проверить соединение» выполняется попытка создать соединение с параметрами, указанными в текущей строке, и выполнить код прописанный в поле «Код проверки».
Почему сделано именно так:
1. Мы копируем компоненты вместо того, чтобы просто создавать новые. Если уже создан компонент с одной из имеющихся concntr.dll, и мы создаем второй, то вместо создания второго компонента программа выдается ошибку 80110802. Решение создавать копии компонентов, а потом их править подсказал user982256 в комментарии к статье «Параллельное использование нескольких версий COM control (несколько версий платформ)».
2. Создаем отдельные приложения для каждой версии платформы. Если компоненты разных версий размещать в одном приложении, то при последовательном использовании разных компонентов, выдается ошибка "-2147024769(0x8007007F): The specified procedure could no be found.".
Видимо, первый из используемых компонентов как-то кэшируется, и второй перестает работать.
P.S. Хочу выразить свою огромную благодарность Дмитрию Петрову за помощь в оформлении этой статьи.
P.S.S. После написания нашел статью «COM соединения с базами 1С на различных версиях платформы "Без перерегистрации и СМС"», где в комментариях рассматриваются все возникшие у меня ошибки, и дается рецепт их исправления, но все равно решил статью опубликовать, чтобы можно было на эти ошибки и не натыкаться.