Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ATL COM class registration .rgs file defaults

I'm creating a COM server executable, and have run into a problem with class registration. When I created my class object, the automatically generated .rgs file looked like this:

HKCR
{
    NoRemove CLSID
    {
        ForceRemove {4C6DAD45-64B4-4C55-81C6-4CE125226421} = s 'Test Class'
        {
            ForceRemove Programmable
            LocalServer32 = s '%MODULE%'
            {
                val ServerExecutable = s '%MODULE_RAW%'
            }
            TypeLib = s '{EAA173CA-BDBC-463A-8B7A-B010EFA467BC}'
            Version = s '1.0'
        }
    }
}

This created the registry entries correctly for the CLSID. However, when attempting to call CoCreateInstance externally, I was experiencing a hang.

hr = CoCreateInstance( __uuidof(Test), NULL, CLSCTX_ALL, __uuidof(ITest), (void**)&pTest);

After looking at a few other projects for examples, I noticed that they all had registry entries of the type:

HKEY_CLASSES_ROOT\<MODULE>.<CLASS>
HKEY_CLASSES_ROOT\<MODULE>.<CLASS>\CLSID

I investigated the .rgs files for these classes, and noticed they had extra entries not present in my .rgs file. I added them to mine, changing it to:

HKCR
{
    TestModule.Test = s 'Test Class'
    {
        CLSID = s '{4C6DAD45-64B4-4C55-81C6-4CE125226421}'
    }

    NoRemove CLSID
    {
        ForceRemove {4C6DAD45-64B4-4C55-81C6-4CE125226421} = s 'Test Class'
        {
            ForceRemove Programmable
            LocalServer32 = s '%MODULE%'
            {
                val ServerExecutable = s '%MODULE_RAW%'
            }
            TypeLib = s '{EAA173CA-BDBC-463A-8B7A-B010EFA467BC}'
            Version = s '1.0'
        }
    }
}

And lo and behold, my CoCreateInstance call no longer hung, and I was able to properly retrieve a pointer to an ITest interface.

Now, my question is, with the above particulars in mind, how can I ensure that any future classes I create have this correct .rgs file format? Is there some option I'm missing when creating the class objects? Or will I need to manually add the above for every class I create?

I'm using Visual Studio 2010.

like image 762
Jack Smith Avatar asked Apr 20 '11 04:04

Jack Smith


People also ask

What is a .RGS file?

rgs file (containing information for registering the component) is used. For more information on . rgs files, see The ATL Registry Component (Registrar). This attribute requires that the coclass, progid, or vi_progid attribute (or another attribute that implies one of these) also be applied to the same element.

How does RGS file work?

rgs file contents is emdebbed as a resource. Later you call regsvr32, it loads the DLL, runs DllRegisterServer() which in turn calls CComModule::UpdateRegistryFromResource() , which loads the . rgs file contents from the resources of that DLL, parses it and modifies the registry.


2 Answers

That's the ProgID for the coclass. It is primarily used by scripting languages, the ones that use late binding. CreateObject() is the usual function name. That this has anything to do with a hang is unexplainable, you'd better debug it.

The .rgs entry is otherwise automatically generated by the ATL wizard. The ProgID edit box is the lower right one. It doesn't get filled in automatically like the rest of them, you probably missed it.

like image 143
Hans Passant Avatar answered Nov 11 '22 13:11

Hans Passant


Sorry for coming five years later... I got a similar issue with ATL COM wizard using Visual Studio 2015 pro. (error 0x80080005 - Server execution failed) It looks like a bug on the ATL COM wizard (since some VS releases, and still not corrected on the latest VS2015).

I found an answer with a manual correction on this MS page: https://connect.microsoft.com/VisualStudio/feedback/details/782281/catlservicemodulet-not-registering-components

The above link is no longer available. However, the issue is explained in this blog: https://blogs.msdn.microsoft.com/jigarme/2008/05/07/cocreateinstance-returns-0x80080005-for-visual-studio-2008-based-atl-service/

Basically, the wizard fails to add the AppID registry entry in the associated rgs file:

NoRemove CLSID
{
    ForceRemove {...} = s '...'
    {
        ...
        val AppID = s '%APPID%'
    }
}

The .rgs files are not completely filled by the wizard. Hope this helps.

like image 34
Carl Avatar answered Nov 11 '22 13:11

Carl