1
votes

I need to make a custom COM object that is going to end up looking similar to this:

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

};

This object is going to end up being passed as a property to the window javascript object in internet explorer so that I can call the functions I define in this class from JavaScript.

My question is, if this is all done in a single executable, do I need to register the COM object in the Registry? If yes, how do I do that if my COM object is in an executable?

2
Yes, you can do this without having to update the registry. You can use registration-free COM, or you can go old-school and use CoRegisterClassObject (I'm assuming that you are hosting a webview control in-process.)Raymond Chen
@RaymondChen This worked for me, if you add it as an answer Ill accept your post. Thankstt9
Feel free to post the answer yourself (providing the level of detail that you feel appropriate) and accept it. I'm not sure the comment counts as an answer because it's just a link to an off-site resource.Raymond Chen
I once made a comment that I considered to be too insignificant to be an answer then someone posted an answer that was essentially what I said and it was accepted. The person that posted the question was not understanding of my frustration. I have learned to post answers even if they seem too small.user34660

2 Answers

1
votes

As user @RaymondChen pointed out in the comments there is a function CoRegisterClassObject here, which can be used to register COM classes without needed to add them to the registry.

This of course only allows you to use that COM class in the scope of the executable which registered it.

1
votes

It is the job of an object that implements IClassFactory to construct the class.

You already have your CLSID_ClientCommunicator. Now you just need to supply an IClassFactory object that can construct it:

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;
   }
}

You now have:

  • your CLSID_ClientCommunicator
  • your IClassFactory that can construct it

You register the two with COM using CoRegisterClassObject:

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
);

So now, if someone in your process tries to construct your class:

IUnknown cc = CreateComObject(CLSID_ClientCommunicator);

it will just work; even though the class is not registered in the registry.

Bonus

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;
}