【问题标题】:Reg-Free Out-of-process COM server eventsReg-Free 进程外 COM 服务器事件
【发布时间】:2015-05-23 16:22:46
【问题描述】:

我们正在尝试将进程内 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 创建的控件,但不适用于事件。 DispEventAdvise 不断返回 CONNECT_E_CANNOTCONNECT 导致接收器上 DIID__IControlEvents 的 QueryInterface 返回 E_NOINTERFACE。

我们确实需要在不在注册表中注册控件的情况下使其正常工作。我们还尝试使用清单文件和单独的代理/存根 DLL 对其进行注册,但没有成功。


【问题讨论】:

  • 我认为问题不在于事件接口的 PS 不可用(您试图通过 CoRegisterPSClsid 调用解决的问题)。问题是托管类型库需要可用,然后将在其上应用库存代理/存根实现。您需要通过无注册 COM 提供类型信息/库:清单、激活上下文等。
  • 请记住,当您使用清单时,您的最后一个 sn-p 不会被使用。我推测服务器失败了,因为它不知道要使用什么代理/存根。将清单也包含在服务器中,然后重试。
  • @RomanR.:我们已经尝试将类型库添加到清单中,但没有任何成功。
  • @HansPassant:好吧,即使有清单,有或没有最后一个 sn-p 都会有所不同。

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


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2014-02-18
    • 2010-09-23
    • 2013-01-20
    • 2012-09-06
    • 1970-01-01
    • 2010-12-07
    • 2011-05-17
    • 2012-10-10
    • 2010-11-18
    相关资源
    最近更新 更多