无Reg-Free进程外COM服务器事件

时间:2015-03-20 09:39:42

标签: c++ com registration-free-com

我们正在尝试将COM对象更改并处理为进程外COM对象。新进程只是将Dispatch传递给以前使用的COM对象,因此我们可以选择返回到进程内对象。 这工作正常,但我们遇到有关事件的问题。进程外服务器拦截先前使用的COM对象的事件,并将这些事件传递给也在工作的自己的事件接口。但问题是,当进程外服务器未在Windows注册表中注册时,客户端无法使用DispEventAdvise连接到此事件接口。

服务器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创建Control,但不适用于事件。 DispEventAdvise一直返回CONNECT_E_CANNOTCONNECT,因为接收器上的DIID__IControlEvents的QueryInterface返回E_NOINTERFACE。

我们确实需要在注册表中注册控件的情况下才能正常工作。我们还尝试使用清单文件注册它,并且还单独代理/存根DLL但没有成功。


1 个答案:

答案 0 :(得分:1)

我们最终只在注册表中注册了调度事件接口,以便正确注册存根类。它现在已注册"但没有任何文件引用。所以我们仍然可以进行并排安装。