我可以创build和使用COM类而不注册它在registry中?

我需要做一个自定义的COM对象,最终会看起来类似于这个:

static const GUID IID_ClientCommunicator = { 0x5219b44a, 0x874, 0x449e,{ 0x86, 0x11, 0xb7, 0x8, 0xd, 0xbf, 0xa6, 0xab } }; static const GUID CLSID_ClientCommunicator = { 0x5219b44b, 0x874, 0x449e,{ 0x86, 0x11, 0xb7, 0x8, 0xd, 0xbf, 0xa6, 0xab } }; class ATL_NO_VTABLE CClientCommunicator: public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CClientCommunicator, &CLSID_ClientCommunicator>, public IDispatchImpl<CClientCommunicator, &IID_ClientCommunicator, 0, /*wMajor =*/ 1, /*wMinor =*/ 0> { public: //Custom functions }; 

这个对象最终会被作为一个属性传递给IE浏览器中的窗口javascript对象,这样我就可以调用我在JavaScript中定义的这个类的函数。

我的问题是,如果这一切都在一个单一的可执行文件中完成,我是否需要在registry中注册COM对象? 如果是的话,如果我的COM对象在可执行文件中,我该怎么做呢?

正如用户@RaymondChen在注释中指出的那样,在这里有一个函数CoRegisterClassObject ,它可以用来注册COM类而不需要将它们添加到注册表中。

这当然只允许你在注册它的可执行文件的范围中使用那个COM类。

实现IClassFactory来构造类是一个对象的工作。

你已经有你的CLSID_ClientCommunicator 。 现在你只需要提供一个可以构造它的IClassFactory对象:

 private class ClientCommunicatorFactory : ComObject, IClassFactory { //IClassFactory methods HRESULT CreateInstance(IUnknown unkOuter, Guid iid, out obj) { ClientCommunicator cc = new CClientCommunicator(); HRESULT hr = cc.QueryInterface(iid, out obj); return hr; } } 

你现在有:

  • 你的CLSID_ClientCommunicator
  • 你的IClassFactory可以构造它

使用CoRegisterClassObject注册两个COM:

 IClassFactory factory = new ClientCommunicatorFactory(); DWORD dwCookie; //cookie to keep track of our registration CoRegisterClassObject( CLSID_ClientCommunicator, // the CLSID to register factory, // the factory that can construct the object CLSCTX_INPROC_SERVER, // can only be used inside our process REGCLS_MULTIPLEUSE, // it can be created multiple times out dwCookie // cookie we can later use to delete the registration ); 

所以,现在,如果你的流程中有人试图构建你的课堂:

 IUnknown cc = CreateComObject(CLSID_ClientCommunicator); 

它只会工作; 即使该类没有在注册表中注册。

奖金

 IUnknown CreateComObject(Guid clsid) { IUnknown unk; HRESULT hr = CoCreateInstance(clsid, null, CLSCTX_INPROC_SERVER, IID_IUnknown, out unk); if (Failed(hr)) throw new EComException(hr); return unk; }