C # - EasyHook CoCreateInstance - PullRequest
       36

C # - EasyHook CoCreateInstance

1 голос
/ 22 октября 2009

Я работаю с библиотекой с открытым исходным кодом EasyHook .

То, что я пытаюсь сделать, это подключиться, когда приложение VB6 вызывает CoCreateInstance из ole32.dll для определенного CLSID, возвращает мою собственную реализацию C # для объекта, а не истинный COM-объект. Моя реализация C # основана на том же интерфейсе, который tlbimp.exe выдает для COM-объекта, который я хочу заменить.

Моя ловушка работает, и я могу подключаться к вызовам, регистрировать данные о вызове, а затем p / invoc CoCreateInstance из C #, чтобы приложение VB6 могло работать в обычном режиме.

Я замечаю, что COM-объект, который я хочу заменить, не проходит через мой хук.

Кто-нибудь знает, как VB6 загружает файлы ocx под капотом? Я подключаюсь к правильному вызову API?

Или то, что я пытаюсь сделать, невозможно из-за природы .Net?

ОБНОВЛЕНИЕ: альтернативное решение - написать COM-объект для замены старого, но мы не можем заставить это работать. Вот старый пост, который я закрыл на эту тему: Заменить COM-объект

ОБНОВЛЕНИЕ: После дальнейшей проверки мы можем regsvr32 / u старый файл ocx и использовать regasm для регистрации нашей .Net DLL. Мы помещаем MessageBox в конструктор нашего COM-объекта, и приложение VB6 загружается и выдает окно, но оно падает, как только делает первый вызов метода для объекта.

Я подозреваю, что у нас неправильные сигнатуры методов, также мы используем то, что нам дал tlbimp.exe, когда мы запустили его на целевом ocx, который мы хотим заменить. Возможно ли, что tlbimp вносит изменения в сигнатуры, которые не позволяют приложениям VB6 загружать нашу сборку?

Например, иногда подпись COM будет выглядеть так:

HRESULT MyMethod(IUnknown* ppv);

И tlbimp.exe выдаст C # что-то вроде:

IUnknown MyMethod();

Что выглядит намного чище для разработчика на C #. Кто-нибудь знает об этом или хорошую статью, которая может объяснить, как написать «двоичную совместимую» COM-сборку из C # для замены файла ocx?

Ответы [ 2 ]

3 голосов
/ 22 октября 2009

Пара комментариев: во-первых, VB6 не использует CoCreateInstance для «локальных» классов, то есть классов из того же проекта - он вызывает «конструктор» напрямую. Во-вторых, вам нужно подключить CoCreateInstance к разделу импорта каждого dll / ocx, из которого можно создать CLSID.

Лучший способ - просто зарегистрировать «обновленный» COM-компонент с тем же классом CLSID. Таким образом, оно будет автоматически использоваться клиентским приложением.

Редактировать: Или взгляните на CoTreatAsClass функция.

1 голос
/ 23 октября 2009

Если у вас есть исходный код для исходного компонента, очевидно, VBMigration Partner может обновить компонент VB6 COM до компонента VB.Net, который имеет двоичную совместимость с исходным компонентом VB6 . Я не знаю, поддерживает ли он OCXs.

...