Вопрос

Мы адаптируем наше относительно сложное приложение на стороне клиента (ActiveX / .net / Delphi / C ++ / COM ) для использования SxS для обеспечения развертывания без участия администратора и изоляции от более старых версий нашего продукта.

Мы смогли достичь этой цели почти для всех наших компонентов in proc, таких как наш .net ui, Delphi ui и COM-серверы, которые мы используем в proc, создав файл манифеста, в котором описаны все библиотеки, используемые нашим процессом, без регистрации на клиенте какого-либо из компонентов (почти).

И вот начинается часть " почти ":На данный момент наше приложение вызывает (из своей части c ++) сервер out of proc ActiveX (Delphi ActiveX EXE), который, в свою очередь, сам вызывает другой набор серверов out of proc ActiveX (плагины сторонних производителей, здесь подходит все, Delphi, C ++, любая вещь, если она находится вне proc ActiveX EXE и реализует наши интерфейсы).

Как мы знаем SxS не поддерживает серверы ActiveX вне proc.И мы не можем использовать эти объекты, как на серверах proc com, в нашем основном процессе, потому что это потребовало бы серьезной перезаписи нашего приложения и, что еще хуже, взлома нашего общедоступного API, который используется сторонними инструментами и поставщиками, взлома API, который мы не можем допустить.

Мы наткнулись на эта статья в котором описывается, как IHTMLDocument2 может быть извлечен из окна Internet Explorer, запущенного в отдельном процессе.Что заставило нас задуматься об этом подходе:

Мы бы создали вторичное приложение-спутник / процесс, который будет запускать ActiveX как на process server.Затем мы будем использовать Lрезультат из объекта и Объект из результата для передачи ссылки на объект ActiveX из вспомогательного приложения в основной процесс приложения.Приложение satellite будет иметь собственный файл манифеста, который позволит ему запускаться в режиме SxS.

Такой же подход будет применен для обмена данными между этим Delphi ActiveX EXE и сторонними плагинами AciveX EXE

Существует альтернативное решение, которое на данный момент мы не предпочитаем предложенному выше решению, которое заключается в использовании прокси-классов .net remoting и .net com для открытия канала связи между двумя процессами путем перевода com-запроса в .net remoting и обратно в com во втором процессе.

Итак, здесь возникает вопрос:

  1. Что вы думаете о таком подходе ?
  2. Видите ли вы лучшее решение этой проблемы ?
Это было полезно?

Решение

Это вполне возможно сделать.Что необходимо:

  • Приложение должно само запускать сервер, а не полагаться для этого на COM.Вам не нужно дополнительное косвенное обращение, предоставляемое реестром, просто используйте CreateProcess().
  • Сервер должен зарегистрировать свои фабрики классов в своем методе main() с помощью CoRegisterClassObject().
  • Важный:идентификатор CLSID, который он использует для каждой фабрики, должен быть изменен, чтобы быть уникальным для каждого экземпляра службы.Это гарантирует, что клиент подключится к правильному серверу.Я просто заменяю идентификатор процесса на CLSID фабрики классов.Клиент также знает идентификатор процесса, поэтому может внести такое же изменение.
  • Приложение должно вызвать CoCreateInstance() в цикле с вызовом Sleep(), чтобы дождаться появления фабрики объектов.Не объявляйте о сбое, пока не пройдет по крайней мере 60 секунд (это меня задело).
  • И приложению, и серверу нужен манифест, содержащий <file> элемент для каждого прокси/заглушки DLL и <comInterfaceExternProxyStub> элементы для каждого удаленного интерфейса.

Другие советы

Алекс,

нобугз прав, вы можете получить доступ к таблице запущенных объектов, чтобы создать экземпляр COM-объекта из текущего запущенного процесса вашего Delphi automation exe.

Однако я обнаружил большую проблему, которую я не могу объяснить.При работе таким образом я могу получить доступ к объекту только через метод variant dispatch.

В принципе, если мой Активный X exe не зарегистрирован, я получаю ошибку "Интерфейс не поддерживается", если я пытаюсь создать экземпляр объекта через интерфейсы, например:

Веб-обновление :Иавтоматизация;

WebUpdate := Совместное обновление.Создать;<-- Ошибка не будет работать


Веб-обновление :Вариант;

Веб-обновление:= CreateOleObject('Веб-обновление.Автоматизация');<-- Работает нормально

Если я зарегистрирую активный x exe-файл с помощью regserver, проблема исчезнет!!

Поди разберись!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top