REGDB_E_CLASSNOTREG с 32-битным клиентом и сервером, реестр выглядит нормально

Я зарегистрировал свой 32-битный внутрипроцессный компонент (только CLSID\{clsid}, MyComponent.1 а также MyComponent ключи и их подразделы) в HKEY_CURRENT_USER\Software\Classes с WOW64-версией regsvr32. Когда я пытаюсь создать его с помощью CoCreateInstance () из моего 32-разрядного процесса, происходит сбой с помощью REGDB_E_CLASSNOTREG.

Но когда я вручную получить HKEY_CLASSES_ROOT\CLSID\{clsid}\InprocServer32 из моего 32-разрядного процесса и загрузить DLL вручную, чтобы вызвать DllGetClassObject (), это успешно!

Я не понимаю Что CoCreateInstance () и CoGetClassObject () делают, что приводит к их отказу с REGDB_E_CLASSNOTREG, когда мой код, который делает то, что должен делать?

//This code fails with REGDB_E_CLASSNOTREG
STDMETHODIMP CreateTestCOM1(ITestCOM ** ppTestCOM, void **ppContext)
{
assert(ppContext!=NULL);
if(ppContext==NULL)
return E_INVALIDARG;

*ppContext = NULL;
HRESULT hr = E_NOTIMPL;
//I tried both CoCreateInstance and CoGetClassObject, they both fail.
#if 0
hr = CoCreateInstance(CLSID_TestCOM, NULL, CLSCTX_INPROC_SERVER, IID_ITestCOM, reinterpret_cast< void ** >(ppTestCOM));
#else
IClassFactory *pFactory = NULL;
hr = CoGetClassObject(CLSID_TestCOM, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, reinterpret_cast< void ** >(&pFactory));
if(SUCCEEDED(hr))
{
hr = pFactory->CreateInstance(NULL, IID_ITestCOM, reinterpret_cast< void ** >(ppTestCOM));
RELEASE_INTERFACE(pFactory);
}
#endif
return hr;
}
//This code works perfectly.
STDMETHODIMP CreateTestCOM3(ITestCOM ** ppTestCOM, void **ppContext)
{
HRESULT hrRet = E_FAIL;
LPTSTR libFileName = NULL;
HKEY hMyClsidKey = NULL;
DWORD err = RegOpenKeyEx(HKEY_CLASSES_ROOT, _T("CLSID\\{4883259C-527B-4327-B9BF-6C22079045B5}"), 0, KEY_READ, &hMyClsidKey);
if(err != ERROR_SUCCESS)
{
_tprintf(_T("CreateTestCOM3: RegOpenKeyEx({CLSID}) failed with error %lu.\n"), err);
hrRet = (err==ERROR_FILE_NOT_FOUND ? REGDB_E_CLASSNOTREG : E_UNEXPECTED);
}
else
{
HKEY hInprocKey = NULL;
err = RegOpenKeyEx(hMyClsidKey, _T("InprocServer32"), 0, KEY_READ, &hInprocKey);
if(err != ERROR_SUCCESS)
{
_tprintf(_T("CreateTestCOM3: RegOpenKeyEx(InprocServer32) failed with error %lu.\n"), err);
hrRet = (err==ERROR_FILE_NOT_FOUND ? REGDB_E_KEYMISSING : E_UNEXPECTED);
}
else
{
TCHAR buf[MAX_PATH] = _T("");
DWORD cbData = sizeof buf;
DWORD type = 0;
err = RegQueryValueEx(hInprocKey, NULL, NULL, &type, reinterpret_cast<LPBYTE>(buf), &cbData);
if(err != ERROR_SUCCESS)
{
_tprintf(_T("CreateTestCOM3: RegQueryValueEx() failed with error %lu.\n"), err);
}
else if(type != REG_SZ)
{
_putts(_T("CreateTestCOM3: Inproc key's default value is not a REG_SZ."));
}
else if((cbData & 1) != 0)
{
_putts(_T("CreateTestCOM3: Inproc key's default value has odd size."));
}
else if(buf[MAX_PATH-1] != _T('\0'))
{
_putts(_T("CreateTestCOM3: Inproc key's default value is too long."));
}
else
{
libFileName = _tcsdup(buf);
_tprintf(_T("CreateTestCOM3: Successfully retrieved DLL path: %s\n"), libFileName);
}

RegCloseKey(hInprocKey);
}
RegCloseKey(hMyClsidKey);
}

if(libFileName != NULL)
{
//LoadLibrary(), GetProcAddress(), DllGetClassObject(), IClassFactory::CreateInstance().
hrRet = CreateTestCOMFromDLL(libFileName, ppTestCOM, ppContext);

free(libFileName);
}
return hrRet;
}

Я также проверил реестр с WOW64-версии regedit, и оба HKEY_CLASSES_ROOT а также HKEY_CURRENT_USER\Software\Classes хорошо выглядеть оттуда.

Отредактировано для добавления: Я на Windows 7, а не XP / Vista. В соответствии с этот, это важное различие.

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]