I have a COM DLL (created with the ATL COM wizard). It comes with the
function:

// DllRegisterServer - Adds entries to the system registry
STDAPI DllRegisterServer(void)
{
// registers object, typelib and all interfaces in typelib
HRESULT hr = _AtlModule.DllRegisterServer();
return hr;
}

This function does get called when the object is registered, but none
of the interfaces I have defined get registered.
Do I need to put code in to manually register my objects? What does
that function register, then?

Thanks,
-PaulH

Re: dllregisterserver not registering com classes by Stuart

Stuart
Wed Jul 19 05:08:46 CDT 2006

PaulH wrote:

> I have a COM DLL (created with the ATL COM wizard). It comes with the
> function:
>
> // DllRegisterServer - Adds entries to the system registry
> STDAPI DllRegisterServer(void)
> {
> // registers object, typelib and all interfaces in typelib
> HRESULT hr = _AtlModule.DllRegisterServer();
> return hr;
> }
>
> This function does get called when the object is registered, but none
> of the interfaces I have defined get registered.
> Do I need to put code in to manually register my objects? What does
> that function register, then?
>
> Thanks,
> -PaulH
>

Have you checked, that each COM class is in the object map of your
server? Opening the .cpp file of the server, you should find something
like that:

BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_<your COM class>, <class name of implementation>)
END_OBJECT_MAP()

Regards,
Stuart

Re: dllregisterserver not registering com classes by PaulH

PaulH
Wed Jul 19 08:42:11 CDT 2006

I don't have any BEGIN_OBJECT_MAP entries, but I think as of VC7, ATL
switched to using OBJECT_ENTRY_AUTO() macros instead. I'm using VS
2005, if that helps.

I do have an OBJECT_ENTRY_AUTO() macro at the bottom of my
wizard-generated IMyModule.h

OBJECT_ENTRY_AUTO(__uuidof(IMyModule), CIMyModule)

as well as a COM_MAP entry in my CIMyModule() class

DECLARE_REGISTRY_RESOURCEID(IDR_IMYMODULE)

BEGIN_COM_MAP(CIMyModule)
COM_INTERFACE_ENTRY(IIMyModule)
COM_INTERFACE_ENTRY2(IDispatch, IComponentRegistrar)
COM_INTERFACE_ENTRY(IComponentRegistrar)
END_COM_MAP()


I wasn't entirely correct before, though. The interface is being
properly put in to the registry, it's only that when I try to access
it, I get the REGDB_E_CLASSNOTREG error from:

{
//...
MyModuleLib::IIMyModulePtr pModule = NULL;
HRESULT hr = pModule.CreateInstance(TEXT("MyModule.IMyModule"));
//...
}


-PaulH

Stuart Redmann wrote:
> PaulH wrote:
>
> > I have a COM DLL (created with the ATL COM wizard). It comes with the
> > function:
> >
> > // DllRegisterServer - Adds entries to the system registry
> > STDAPI DllRegisterServer(void)
> > {
> > // registers object, typelib and all interfaces in typelib
> > HRESULT hr = _AtlModule.DllRegisterServer();
> > return hr;
> > }
> >
> > This function does get called when the object is registered, but none
> > of the interfaces I have defined get registered.
> > Do I need to put code in to manually register my objects? What does
> > that function register, then?
> >
> > Thanks,
> > -PaulH
> >
>
> Have you checked, that each COM class is in the object map of your
> server? Opening the .cpp file of the server, you should find something
> like that:
>
> BEGIN_OBJECT_MAP(ObjectMap)
> OBJECT_ENTRY(CLSID_<your COM class>, <class name of implementation>)
> END_OBJECT_MAP()
>
> Regards,
> Stuart


Re: dllregisterserver not registering com classes by Carl

Carl
Wed Jul 19 08:46:17 CDT 2006

PaulH wrote:
> I wasn't entirely correct before, though. The interface is being
> properly put in to the registry, it's only that when I try to access
> it, I get the REGDB_E_CLASSNOTREG error from:
>
> {
> //...
> MyModuleLib::IIMyModulePtr pModule = NULL;
> HRESULT hr = pModule.CreateInstance(TEXT("MyModule.IMyModule"));
> //...
> }

Does your DLL depend on any other DLLs that aren't on the PATH or in the
same directory? If the COM machinery gets an error loading your DLL, you'll
get back REGDB_E_CLASSNOTREG just as if the regisstry entries were missing.

-cd



Re: dllregisterserver not registering com classes by PaulH

PaulH
Wed Jul 19 10:25:06 CDT 2006

That's an interesting possibility.
According to Dependency Walker, I depend on COREDLL.DLL, OLE32.DLL,
OLEAUT32.DLL, and MSVCR80D.DLL.

The only one of those I can find in the \windows directory is
MSVCR80D.dll. But, I believe the others are fairly necessary system
components, so I can't imagine they're not there, they're probably just
hidden. Is there a way to check for this specific failure condition?

-PaulH

Carl Daniel [VC++ MVP] wrote:
> PaulH wrote:
> > I wasn't entirely correct before, though. The interface is being
> > properly put in to the registry, it's only that when I try to access
> > it, I get the REGDB_E_CLASSNOTREG error from:
> >
> > {
> > //...
> > MyModuleLib::IIMyModulePtr pModule = NULL;
> > HRESULT hr = pModule.CreateInstance(TEXT("MyModule.IMyModule"));
> > //...
> > }
>
> Does your DLL depend on any other DLLs that aren't on the PATH or in the
> same directory? If the COM machinery gets an error loading your DLL, you'll
> get back REGDB_E_CLASSNOTREG just as if the regisstry entries were missing.
>
> -cd


Re: dllregisterserver not registering com classes by PaulH

PaulH
Wed Jul 19 10:28:07 CDT 2006

As a test, I did a LoadLibrary() on each of those DLLs from my test
app. I didn't get any errors back, so I think they're all there.

-PaulH

Carl Daniel [VC++ MVP] wrote:
> PaulH wrote:
> > I wasn't entirely correct before, though. The interface is being
> > properly put in to the registry, it's only that when I try to access
> > it, I get the REGDB_E_CLASSNOTREG error from:
> >
> > {
> > //...
> > MyModuleLib::IIMyModulePtr pModule = NULL;
> > HRESULT hr = pModule.CreateInstance(TEXT("MyModule.IMyModule"));
> > //...
> > }
>
> Does your DLL depend on any other DLLs that aren't on the PATH or in the
> same directory? If the COM machinery gets an error loading your DLL, you'll
> get back REGDB_E_CLASSNOTREG just as if the regisstry entries were missing.
>
> -cd


Re: dllregisterserver not registering com classes by Stuart

Stuart
Thu Jul 20 02:26:36 CDT 2006

>> PaulH wrote:
>>
>>> I have a COM DLL (created with the ATL COM wizard). It comes with
>>> the function:
>>>
>>> // DllRegisterServer - Adds entries to the system registry
>>> STDAPI DllRegisterServer(void)
>>> {
>>> // registers object, typelib and all interfaces in typelib
>>> HRESULT hr = _AtlModule.DllRegisterServer();
>>> return hr;
>>> }
>>>
>>> This function does get called when the object is registered, but
>>> none of the interfaces I have defined get registered.
>>> Do I need to put code in to manually register my objects? What does
>>> that function register, then?

[snipped suggestion that he may have forgotten to put the class id in
the OBJECT_MAP]

> I don't have any BEGIN_OBJECT_MAP entries, but I think as of VC7, ATL
> switched to using OBJECT_ENTRY_AUTO() macros instead. I'm using VS
> 2005, if that helps.
>
> I do have an OBJECT_ENTRY_AUTO() macro at the bottom of my
> wizard-generated IMyModule.h
>
> OBJECT_ENTRY_AUTO(__uuidof(IMyModule), CIMyModule)
>
> as well as a COM_MAP entry in my CIMyModule() class
>
> DECLARE_REGISTRY_RESOURCEID(IDR_IMYMODULE)
>
> BEGIN_COM_MAP(CIMyModule)
> COM_INTERFACE_ENTRY(IIMyModule)
> COM_INTERFACE_ENTRY2(IDispatch, IComponentRegistrar)
> COM_INTERFACE_ENTRY(IComponentRegistrar)
> END_COM_MAP()
>
>
> I wasn't entirely correct before, though. The interface is being
> properly put in to the registry, it's only that when I try to access
> it, I get the REGDB_E_CLASSNOTREG error from:
>

This is getting a bit confusing. As I see it you have a class called
IMyModule that exposes an interface IIMyModule. That means I suspect you
have something like the following lines in your .idl file:

[
...
]
interface IIModule : ...

[
...
]
coclass IMyModule
{
...
};

This naming sceme is quite confusing, since one should only use the
prefix 'I' for interface names. You idl-file should read something like
that:
[...] interface IModule : ... {...};
[...] coclass MyModule {...};

When you say that your _interface_ is properly registered in the
registry, you certainly means that your _coclass_ is properly registered.

> {
> //...
> MyModuleLib::IIMyModulePtr pModule = NULL;
> HRESULT hr = pModule.CreateInstance(TEXT("MyModule.IMyModule"));
> //...
> }

Have you tried to create an instance of your coclass by class id? Under
VC6.0 this can be done by simply calling CreateInstance for a given
smart pointer without any arguments:
HRESULT hr = pModule.CreateInstance ();

Regards,
Stuart