А можно озвучить решаемую задачу более подробно? Обрабатывать неизвестно какие события с неизвестно какой сигнатурой от неизвестно каких серверов — задача понятная для разного рода wizard'ов, создающих врапперы, но с этим вроде как должны справиться TypeLibConverter или AxImporter . А обычное приложение какую пользу может из этого извлечь?
В принципе, если серверы генерят события через dispinterface, то достаточно просто их принять одним объектом, реализующем IDispatch. Нужно просто в QueryInterface на запрос диспинтерфейсов отдавать IDispatch, и все события пойдут в IDispatch.Invoke. В нативном коде это делается элеменарно, такую реализацию часто используют в качестве базового класса приёмников событий. Вероятно, можно попробовать провернуть это и в NET.
Здравствуйте, Jolly Roger, Вы писали:
JR>Здравствуйте, PeterPan, Вы писали:
JR>А можно озвучить решаемую задачу более подробно? Обрабатывать неизвестно какие события с неизвестно какой сигнатурой от неизвестно каких серверов — задача понятная для разного рода wizard'ов, создающих врапперы, но с этим вроде как должны справиться TypeLibConverter или AxImporter . А обычное приложение какую пользу может из этого извлечь?
темы, то сигнатура событий известна. Как получить мета описания типов, методов аргументов я там описал.
Как принимать события я там также описал. Мне остается закончить динамическую генерацию интерфейса и объекта приемника событий и "подсунуть" его в СОМ-объекты — генератор событий.
JR>В принципе, если серверы генерят события через dispinterface, то достаточно просто их принять одним объектом, реализующем IDispatch. Нужно просто в QueryInterface на запрос диспинтерфейсов отдавать IDispatch, и все события пойдут в IDispatch.Invoke. В нативном коде это делается элеменарно, такую реализацию часто используют в качестве базового класса приёмников событий. Вероятно, можно попробовать провернуть это и в NET.
темы, то сигнатура событий известна. Как получить мета описания типов, методов аргументов я там описал. PP>Как принимать события я там также описал. Мне остается закончить динамическую генерацию интерфейса и объекта приемника событий и "подсунуть" его в СОМ-объекты — генератор событий.
Из той темы конечная цель так-же не ясна, как и из этой. Если сигнатуры заранее известны, то скорее всего пляски с рантайм генерацией типов вообще не нужны. Впрочем, дело Ваше.
темы, то сигнатура событий известна. Как получить мета описания типов, методов аргументов я там описал. PP>>Как принимать события я там также описал. Мне остается закончить динамическую генерацию интерфейса и объекта приемника событий и "подсунуть" его в СОМ-объекты — генератор событий.
JR>Из той темы конечная цель так-же не ясна, как и из этой. Если сигнатуры заранее известны, то скорее всего пляски с рантайм генерацией типов вообще не нужны. Впрочем, дело Ваше.
Постараюсь описать задачу подробнее
На старте известны: ProgID COM объекта и сигнатура событий (название, тип возвращаемого значения, названия аргументов и их типы) этого объекта, пусть, например, это будет void OnError(string msg).
Цель — подписаться на событие этого COM-объекта в среде .Net Framework, в нашем случае — иметь возможность журналировать msg.
К сожалению я не нашел способа делать это без рантайм генерации типов. Если есть такая возможность, буду признателен за пример.
Здравствуйте, PeterPan, Вы писали:
PP>Здравствуйте, Jolly Roger, Вы писали:
JR>>Здравствуйте, PeterPan, Вы писали:
PP>>>Если имеется в виду задача из этой
темы, то сигнатура событий известна. Как получить мета описания типов, методов аргументов я там описал. PP>>>Как принимать события я там также описал. Мне остается закончить динамическую генерацию интерфейса и объекта приемника событий и "подсунуть" его в СОМ-объекты — генератор событий.
JR>>Из той темы конечная цель так-же не ясна, как и из этой. Если сигнатуры заранее известны, то скорее всего пляски с рантайм генерацией типов вообще не нужны. Впрочем, дело Ваше.
Здравствуйте, PeterPan, Вы писали:
PP>На старте известны: ProgID COM объекта и сигнатура событий (название, тип возвращаемого значения, названия аргументов и их типы) этого объекта, пусть, например, это будет void OnError(string msg). PP>Цель — подписаться на событие этого COM-объекта в среде .Net Framework, в нашем случае — иметь возможность журналировать msg.
. Там не совсем такая ситуация, но предложенное решение — то, что нужно Вам, и оно работает, я проверил. Если всё-же есть ещё какие-то нюансы, не указанные Вами — вот ссылка 2
Но прежде проверьте, вполне возможно, что Вам будет достаточно объявить класс без явных интерфейсов, с публичным методом OnError(string msg) и аттрибутом ClassInterface(ClassInterfaceType.AutoDispatch)
Здравствуйте, Jolly Roger, Вы писали:
JR>Здравствуйте, PeterPan, Вы писали:
PP>>На старте известны: ProgID COM объекта и сигнатура событий (название, тип возвращаемого значения, названия аргументов и их типы) этого объекта, пусть, например, это будет void OnError(string msg). PP>>Цель — подписаться на событие этого COM-объекта в среде .Net Framework, в нашем случае — иметь возможность журналировать msg.
JR>Для описанного случая — здесь
. Там не совсем такая ситуация, но предложенное решение — то, что нужно Вам, и оно работает, я проверил. Если всё-же есть ещё какие-то нюансы, не указанные Вами — вот ссылка 2
, но это я пока не проверял.
JR>Но прежде проверьте, вполне возможно, что Вам будет достаточно объявить класс без явных интерфейсов, с публичным методом OnError(string msg) и аттрибутом ClassInterface(ClassInterfaceType.AutoDispatch)
Не вижу по ссылкам то, что мне надо, а именно подписку на события.
Давайте по порядку:
1.Я создаю COM -объект по progID
Type tp = Type.GetTypeFromProgID(progID);
object comObject = Activator.CreateInstance(tp);
Здравствуйте, PeterPan, Вы писали:
PP>Не вижу по ссылкам то, что мне надо, а именно подписку на события.
Хм, а причём тут подписка? Подписка ровно так-же, как Вы собирались с ручной генерации типов
var cpc = comObject as IConnectionPointContainer;
IConnectionPoint cp;
cpc.FindConnectionPoint(ref EventsIId, out cp);
var sink = new MyEventSink();
cp.Advise(sink, out cookie);
Только вместо сгенерированного MyEventSink пердать в Advise можно попробовать TransparentProxy из примера.