Мы пытаемся изменить COM-объект и объект proc вне COM-объекта. Новый процесс просто передает Dispatch для ранее использованного COM-объекта, поэтому мы можем по желанию вернуться к объекту in-proc. Это прекрасно работает, но мы сталкиваемся с проблемами, связанными с событиями. Внепроцессный сервер перехватывает события ранее использованного COM-объекта и передает их в собственный интерфейс событий, который также работает. Но проблема в том, что клиент не может подключиться к этому интерфейсу событий, используя DispEventAdvise, когда сервер вне процесса не зарегистрирован в реестре Windows.Reg-Free Внеочередные события COM-сервера
Сервер IDL выглядит следующим образом:
[
object,
uuid(www),
dual,
oleautomation,
nonextensible,
helpstring("IControl Interface"),
pointer_default(unique)
]
interface IControl : IDispatch
{
[id(1)] HRESULT CreateDispatch([out] IDispatch** ppDispatch);
};
[
uuid(xxx),
version(1.0),
helpstring("Control Type Library")
]
library ControlLib
{
importlib("stdole2.tlb");
[
uuid(yyy),
helpstring("IControlEvents Interface"),
nonextensible
]
interface IControlEvents : IUnknown
{
[id(1)] HRESULT MyEvent(void);
};
[
uuid(zzz),
helpstring("_IControlEvents Interface")
]
dispinterface _IControlEvents
{
interface IControlEvents;
};
coclass Control
{
[default] interface IControl;
[default, source] dispinterface _IControlEvents;
};
};
Мы добавили control_i.c, control_p.c и dlldata.c для клиента и сервера. И оба выполняют следующие шаги для регистрации прокси/заглушки.
PrxDllGetClassObject(IID_IControl, IID_IUnknown, (void **)&punk);
CoRegisterClassObject(IID_IControl, punk, CLSCTX_INPROC_SERVER, REGCLS_SINGLEUSE, &dwRCO);
CoRegisterPSClsid(IID_IControl, IID_IControl);
CoRegisterPSClsid(IID_IControlEvents, IID_IControl);
CoRegisterPSClsid(DIID__IControlEvents, IID_IControl);
Это работает для элемента управления, который создается с использованием CoCreateInstance, но не для событий. DispEventAdvise продолжает возвращать CONNECT_E_CANNOTCONNECT, потому что QueryInterface для DIID__IControlEvents на приемнике возвращает E_NOINTERFACE.
Нам действительно нужно получить эту работу без регистрации элемента управления в реестре. Мы также пытались зарегистрировать его с помощью файлов манифеста, а также отдельные DLL-файлы прокси-сервера, но не имели успеха.
Я не думаю, что проблема заключается в недоступности PS для интерфейса событий (что вы пытаетесь исправить с помощью вызова CoRegisterPSClsid). Проблема в том, что библиотека типа хостинга должна быть доступна, а затем поверх нее будет применяться реализация прокси-сервера/заглушки. Вам нужно сделать информацию о типе/библиотеку доступной через reg-free COM: манифест, контекст активации и т. Д. –
Имейте в виду, что ваш последний фрагмент не будет использоваться, когда вы используете манифест. Я бы предположил, что сервер терпит неудачу, так как он не знает, какой прокси/заглушка использовать. Включите манифест на сервере и повторите попытку. –
@RomanR: Мы уже пытались добавить библиотеку типов в манифест, но также без каких-либо успехов. –