Yes, it basically makes no sense to me that VB6 doesn't look up the registry keys. It just doesn't. COM object creation is usually done like this (simplified):
All this should be happening in both .Net and VB6. I see no other way around it. In your case, theIClassFactory is returning 0x80040111 if the loaded DLL doesn't supply the COM object that corresponds to the given CLSID; and you get 0x80040111 probably from step 2 from the call toCoCreateInstance() when it doesn't find the desired CLSID under HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID.
-------------
1. I guess the next thing to do would be the tough job of debugging the class factory code.
2. To do this, you need to start debugging your COM DLL and set the C# client app as the startup application.
2.1 Via project properties, set the debugger type to "Mixed" so that you can see the C# client code.
2.2 Then place a breakpoint in your global DllGetClassObject() function. This function was generated by the ATL wizard for your DLL. It should look something like the following :
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
return _AtlModule.DllGetClassObject(rclsid, riid, ppv);
}
2.3 Start debugging. Note well that if you are able to reach the DllGetClassObject() function, it is clear that your COM DLL has been registered correctly. If you are not able to even reach DllGetClassObject(), something has gone wrong and we may be back to registration problems again.
2.4 If you do reach DllGetClassObject(), step through all the way until you reach the AtlComModuleGetClassObject() function (this is the ATL source code from my machine which uses VS2008) :
ATLINLINE ATLAPI AtlComModuleGetClassObject(_ATL_COM_MODULE* pComModule, REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
if (ppv == NULL)
return E_POINTER;
*ppv = NULL;
ATLASSERT(pComModule != NULL);
if (pComModule == NULL)
return E_INVALIDARG;
if (pComModule->cbSize == 0) // Module hasn't been initialized
return E_UNEXPECTED;
HRESULT hr = S_OK;
for (_ATL_OBJMAP_ENTRY** ppEntry = pComModule->m_ppAutoObjMapFirst; ppEntry < pComModule->m_ppAutoObjMapLast; ppEntry++)
{
if (*ppEntry != NULL)
{
_ATL_OBJMAP_ENTRY* pEntry = *ppEntry;
if ((pEntry->pfnGetClassObject != NULL) && InlineIsEqualGUID(rclsid, *pEntry->pclsid))
{
if (pEntry->pCF == NULL)
{
CComCritSecLock<CComCriticalSection> lock(pComModule->m_csObjMap, false);
hr = lock.Lock();
if (FAILED(hr))
{
ATLTRACE(atlTraceCOM, 0, _T("ERROR : Unable to lock critical section in AtlComModuleGetClassObject\n"));
ATLASSERT(0);
break;
}
if (pEntry->pCF == NULL)
hr = pEntry->pfnGetClassObject(pEntry->pfnCreateInstance, __uuidof(IUnknown), (LPVOID*)&pEntry->pCF);
}
if (pEntry->pCF != NULL)
hr = pEntry->pCF->QueryInterface(riid, ppv);
break;
}
}
}
if (*ppv == NULL && hr == S_OK)
hr = CLASS_E_CLASSNOTAVAILABLE;
return hr;
}
Note the highlighted error code CLASS_E_CLASSNOTAVAILABLE. This error code has value0x80040111. Step through and see in what situation will this error code be returned.
2.5 Best of luck, Jicky.