Freigeben über


Registration-free COM

There is a great article on MSDN by Dave Templin about new VS 2005 functionality that allows you to isolate COM components and avoid COM DLL hell. The technique only works on Windows XP though (see Limitations of Reg-Free COM). But what if you need solution now and your application has to run on earlier versions on Windows? Here is what you can do.

You only have to register your COM component if you want to be able to instantiate it using CoCreateInstance. However, if you are consuming your own COM components, you don't have to use CoCreateInstance. Here is how you can instantiate COM component without registering it in OS registry.

1. Locate COM component DLL.

2. Load it into memory using LoadLibrary.

3. Locate DllGetClassObject function exported from the DLL using GetProcAddress Win32 API.

4. Call DllGetClassObject and obtain IClassFactory interface of your component class factory. ATL automatically implements and exports this function for you.

5. Invoke IClassFactory::CreateInstance.

MSDN tells you not to call DllGetClassObject directly which is generally correct. However, if it is your own component and the component is native, the described technique will work. You can even maintain your own registry in a OS Registry subkey or in an external XML file. You can write MyCreateInstance that will be locating components by their CLSID in your private component registry and create object instances.

You can download Visual Studio SDK and discover that VS maintains its local component registry hive in HKLM\Software\Microsoft\VisualStudio\8.0\CLSID where it registers packages and other COM components. This allows different versions of VS to coexist on the same machine.

It is also possible to develop similar approach for COM components implemented in .NET but is a bit more complex.

Comments

  • Anonymous
    November 29, 2005
    Hi I have a .net based .tlb which i want to use in CPP code. May I know how to use it without registration of com. Here is the sample code:

    #include <stdio.h>
    #include <windows.h>
    #include "OBJBASE.h"
    #include <time.h>
    #include "RCSTlbImp.h"
    #import "REWDIntf.tlb" named_guids
    void RCSLinkLib()
    {
    HINSTANCE hins=NULL;
    DWORD dwRetVal = 0;

    CoInitialize(NULL);
    REWDIntf::IRCSManagedInterface pRcsDllInterface= NULL; //Reference to the class

    hins=LoadLibrary("C:/WINDOWS/SYSTEM32/REWDIntf.dll");
    DWORD dwErr = GetLastError();

    RCS_test=(RCSTest)GetProcAddress(hins,"REWDIntf::RCSTest");

    // DllGetClassObject(REWDIntf::CLSID_REWDIntf, REWDIntf::IID_IRCSManagedInterface,reinterpret_cast<void
    *>(&pRcsDllInterface));
    dwErr = GetLastError();
    CoUninitialize();


    }

    void main()
    {
    RCSLinkLib();
    int i = RCS_test(1);
    }
  • Anonymous
    December 22, 2005
    DllGetClassObject is only able to retrieve IClassFactory interface, it cannot retrieve custom interfaces. You need to implement class factory (if you are using ATL, it should acready be there). Then you call DllGetClassObject and receive IClassFactory. Then you call IClassFactory::CreateInstance passing GUID of the desired class and receive back IUnknown from the requested class. Now you can QI the instance to your custom interface.
  • Anonymous
    January 29, 2007
    PingBack from http://lallousx86.wordpress.com/2007/01/29/emulating-cocreateinstance/