Как заставить .NET не использовать зарегистрированный TLB для маршалинга вызовов COM-методов? - PullRequest
3 голосов
/ 30 августа 2010

Текущая конфигурация:

  1. Основное приложение неуправляемое.
  2. Содержит DLL, содержащую TLB, описывающую функции, доступные для модели COM.
  3. Для поддержки веб-служб ASMX загружается платформа .NET и запускается домен ASP.NET, который обслуживает вызовы веб-служб.
  4. Для обслуживания вызовов веб-службы необходимы данные из основного приложения. Итак, мы генерирование сборки Interop из TLB (с использованием tlbimp.exe), а сборки веб-служб используют это Interop для взаимодействия с COM-объектами в основном приложении.

Все работает нормально, пока мы не столкнулись с проблемой версий. Когда на одном компьютере были установлены 2 версии приложения (содержащие 2 версии TLB), обе версии TLB (например, 2.0 и 2.1) регистрируются, и более низкая версия перестает работать. ProcessMonitor показывает, что при попытке вызвать веб-службу экземпляра версии 2.0 он ищет в реестре идентификатор GUID TLB, считывает все вложенные ключи с номерами версий, берет последнюю версию (2.1) и начинает читать ее содержимое. После этого он читает DLL версии 2.1 и не может делать вызовы COM внутри своего собственного процесса - насколько я понимаю из-за проблем с маршалингом.

Как я могу сделать Interop, который бы не требовал наличия TLB (по крайней мере, наличия зарегистрированного TLB) для выполнения внутрипроцессных COM-вызовов?

Заранее спасибо.

1 Ответ

3 голосов
/ 06 сентября 2010

Ну, вот как проблема была решена.

.NET, похоже, загружает TLB для построения новой квартиры для каждого потока ASP.NET (все происходит, когда новый поток впервые пытается получить доступ к какому-либо COM-интерфейсу).Кажется, для этой цели используются функции CoMarshalInterThreadInterfaceInStream и CoGetInterfaceAndReleaseStream.Я не могу доказать это, но вызов этих функций вызывает тот же эффект: запрос системного реестра и загрузка TLB самой высокой совместимой версии (та же основная версия, самая высокая младшая версия).На поведение CoGetInterfaceAndReleaseStream манифест не влияет.

Таким образом, реальная проблема заключается в том, что наш проект не следует правилам, которые Microsoft рекомендует для нумерации версий: COM-интерфейсы, имеющие одну и ту же основную версию, должны быть совместимы.получить адрес функции LoadTypeLib (OleAut32.dll) и установить инструкцию JMP в ее начале.JMP переходит к нашей реализации, которая проверяет имя загружаемого TLB и, если это один из известных TLB, перенаправляет чтение в локальный каталог.

...