Могу ли я остановить COM DLL от отображения форм? - PullRequest
2 голосов
/ 18 марта 2009

Чтобы быть более конкретным:

У нас есть веб-сервис (написанный на .Net), который использует большое количество COM-библиотек для основной бизнес-логики (написанный на VB6). Предположим сейчас, что это закрытые библиотеки.

К сожалению, многие из этих библиотек COM реализуют свои собственные сообщения об ошибках или сообщения о проверке; если мы передадим данные, которые не являются полными, или если отсутствует другая зависимость COM, они отобразят диалоговое окно. Эти диалоговые окна являются проблемой ... при работе в IIS эти окна сообщений зависают в запросе, ожидая, пока пользователь не нажмет ok для поля, которое невозможно увидеть.

Кто-нибудь знает способ перехвата этих вызовов пользовательского интерфейса (потенциально это может быть form.show вместо окна сообщений) на стороне .Net, поэтому мы можем вместо этого выдать исключение?

Ответы [ 3 ]

2 голосов
/ 18 марта 2009

Отображение форм - это наименьшая из ваших проблем, если они были написаны на VB6 для использования в настольном приложении. Эти COM-объекты, вероятно, также не ожидают одновременного доступа к нескольким потокам. Это может взорваться очень эффектно или очень тонко.

Если руководство зависит от того, будет ли это работать для 10 000 библиотек, вам необходимо дать им понять, что нарушение предположений о 10 000 кусочков десятилетнего кода не является хорошей идеей.

Если менеджмент достаточно взрослый (и в США), то напомните им о старых рекламных роликах о маргарине: «Это не приятно - обмануть Мать-Природу». Могут случиться плохие вещи.


Я думаю, мне нужно быть более конкретным в отношении "Плохих вещей".

Я предполагаю, что это были COM-объекты VB6, созданные для взаимодействия с приложением или приложениями форм VB6. Эти COM-объекты могли бы тогда разумно предположить, что к ним одновременно обращался только один поток, к ним одновременно обращался только один пользователь, и на самом деле только один поток и один пользователь обращались к ним в течение всей своей жизни.

Как только вы запускаете их на сервере, вы нарушаете их предположения.

Кто может сказать, что это вызовет? Никто не сделал этот анализ, потому что это были базовые (и действительные) предположения! Будет ли код кешировать что-то в локальном потоке? Это сработало бы для оригинального сценария. Возможно, общие данные используются для кэширования информации. Он должен быть заблокирован, если он будет использоваться несколькими потоками, и тогда вам придется надеяться, что информация не меняется для каждого пользователя, потому что разные потоки могут выполняться от имени разных пользователей.

Мне однажды сказали пойти и исправить утечку памяти. Короче говоря, это была не утечка памяти. Это был устаревший неуправляемый код, который предполагал, что он выполняется в настольном или пакетном приложении. В веб-сервисе он выбрасывал мусор по всей куче. Следовательно, он генерировал исключения повсеместно и заставлял другой, не связанный код делать то же самое. Неуправляемые исключения не содержат подробностей, поэтому было невозможно увидеть, что вызвало проблему или как ее решить.

В этом случае мне удалось просто установить блокировку вокруг всего доступа. Это было достаточно хорошо, потому что этот код предполагал пакетную среду, а не интерактивную среду. Этого может быть недостаточно, если ваши COM-объекты предполагают, что их десятилетние требования не изменились из-под них.

Если все COM-объекты могут работать под одним и тем же именем пользователя, это избавит вас от неприятностей. Кроме того, вам, возможно, просто нужно убедиться, что существует только один экземпляр данного объекта за раз, и что весь доступ к нему сериализуется. Для этого используйте оператор SyncLock в VB.NET.

Окончательное решение - создать «управляемый тестом порт» кода. Я бы использовал существующую кодовую базу для создания автоматических модульных тестов (возможно, используя vbunit ). Как только фрагмент кода имеет достаточный охват модульных тестов, вы можете перенести этот код (все еще как COM-объект) на VB.NET. Модульные тесты могут использоваться для подтверждения того, что порт все еще работает.

Такой порт может быть не таким жестким, как вы думаете. «Копировать, вставлять и исправлять ошибки компилятора» довольно хорошо работает между VB6 и VB.NET. Есть даже инструменты, чтобы помочь. Но это автоматизированные тесты, которые делают это практичным. В противном случае у вас возникнут разумные опасения относительно того, насколько хорошо работает порт.

Обратите внимание, что новые COM-объекты все еще должны использоваться оригинальным кодом VB6. На самом деле это должен быть тест.

Обратите внимание, что это будет хорошей возможностью для документирования переносимого кода, так что это станет меньшей проблемой в течение следующих десяти лет. Только не потеряйте документацию!

2 голосов
/ 18 марта 2009

С учетом того, что я не делал этого лично, я считаю, что перехват и перенаправление, которого вы желаете, можно достичь с помощью Win32 Hooks

0 голосов
/ 18 марта 2009

Ознакомьтесь с некоторыми статьями Джесси Каплана в журнале msdn. Его колонка называется CLR Inside Out. Ищите статьи COM Interop. Проблемы доступны для скачивания здесь: http://msdn.microsoft.com/en-us/magazine/cc159440.aspx

Редактировать: Похоже, мистер Каплан является лишь случайным автором этого раздела. Это все еще отличный ресурс для советов по взаимодействию.

...