C++ REGDB_E_CLASSNOTREG,客户端和服务器均为32位,注册表看起来正常

C++ REGDB_E_CLASSNOTREG,客户端和服务器均为32位,注册表看起来正常,c++,com,windows-7-x64,wow64,C++,Com,Windows 7 X64,Wow64,我用WOW64版本的regsvr32在HKEY_CURRENT_USER\Software\Classes中注册了我的32位进程内组件(仅是CLSID\{CLSID}、MyComponent.1和MyComponent键及其子键)。当我尝试使用32位进程中的CoCreateInstance()创建它时,使用REGDB_E_CLASSNOTREG失败 但是当我从32位进程手动检索HKEY_CLASSES\u ROOT\CLSID\{CLSID}\InprocServer32并手动加载DLL以调用D

我用WOW64版本的regsvr32在
HKEY_CURRENT_USER\Software\Classes
中注册了我的32位进程内组件(仅是
CLSID\{CLSID}
MyComponent.1
MyComponent
键及其子键)。当我尝试使用32位进程中的CoCreateInstance()创建它时,使用REGDB_E_CLASSNOTREG失败

但是当我从32位进程手动检索
HKEY_CLASSES\u ROOT\CLSID\{CLSID}\InprocServer32
并手动加载DLL以调用DllGetClassObject()时,它成功了

我不明白。CoCreateInstance()和CoGetClassObject()做了什么,当我的代码完成它们应该做的工作时,它们使用REGDB_E_CLASSNOTREG失败

//此代码与REGDB_E_CLASSNOTREG一起失败
STDMETHODIMP CreateTestCOM1(ITestCOM**ppTestCOM,void**ppContext)
{
断言(ppContext!=NULL);
if(ppContext==NULL)
返回E_INVALIDARG;
*ppContext=NULL;
HRESULT hr=E_NOTIMPL;
//我尝试了CoCreateInstance和CoGetClassObject,但都失败了。
#如果0
hr=CoCreateInstance(CLSID_TestCOM,NULL,CLSCTX_INPROC_SERVER,IID_ITestCOM,reinterpret_cast(ppTestCOM));
#否则
IClassFactory*pFactory=NULL;
hr=CoGetClassObject(CLSID_TestCOM、CLSCTX_INPROC_SERVER、NULL、IID_IClassFactory、重新解释\u cast(&pFactory));
如果(成功(hr))
{
hr=pFactory->CreateInstance(NULL,IID_ITestCOM,reinterpret_cast(ppTestCOM));
发布接口(PFFactory);
}
#恩迪夫
返回人力资源;
}
//这段代码工作得很好。
STDMETHODIMP CreateTestCOM3(ITestCOM**ppTestCOM,void**ppContext)
{
HRESULT hrRet=E_失败;
LPTSTR libFileName=NULL;
HKEY-hMyClsidKey=NULL;
DWORD err=RegOpenKeyEx(HKEY_CLASSES_ROOT,_T(“CLSID\\{4883259C-527B-4327-B9BF-6C22079045B5}”)、0、KEY_READ和hMyClsidKey;
如果(错误!=错误\u成功)
{
_tprintf(_T(“CreateTestCOM3:RegOpenKeyEx({CLSID})失败,错误为%lu。\n”)、错误;
hrRet=(err==找不到错误文件?REGDB\u E\u CLASSNOTREG:E\u意外);
}
其他的
{
HKEY hInprocKey=NULL;
err=RegOpenKeyEx(hMyClsidKey,_T(“InprocServer32”)、0、KEY\u READ和hInprocKey);
如果(错误!=错误\u成功)
{
_tprintf(_T(“CreateTestCOM3:RegOpenKeyEx(InprocServer32)失败,错误为%lu。\n”),错误;
hrRet=(err==找不到错误文件?REGDB\u E\u KEYMISSING:E\u意外);
}
其他的
{
TCHAR buf[MAX_PATH]=\u T(“”);
DWORD cbData=buf的尺寸;
DWORD类型=0;
err=regqueryvaluex(hInprocKey、NULL、NULL和type、reinterpret_cast(buf)和cbData);
如果(错误!=错误\u成功)
{
_tprintf(_T(“CreateTestCOM3:RegQueryValueEx()失败,错误为%lu.\n”),err);
}
else if(类型!=REG_SZ)
{
_putts(_T(“CreateTestCOM3:Inproc键的默认值不是REG_SZ”);
}
如果((cbData&1)!=0,则为else
{
_putts(_T(“CreateTestCOM3:Inproc键的默认值大小为奇数”);
}
else if(buf[MAX\u PATH-1]!=\T('\0'))
{
_putts(_T(“CreateTestCOM3:Inproc键的默认值太长”);
}
其他的
{
libFileName=_tcsdup(buf);
_tprintf(_T(“CreateTestCOM3:成功检索DLL路径:%s\n”)、libFileName);
}
RegCloseKey(hInprocKey);
}
RegCloseKey(hMyClsidKey);
}
if(libFileName!=NULL)
{
//LoadLibrary()、GetProcAddress()、DllGetClassObject()、IClassFactory::CreateInstance()。
hrRet=CreateTestCOMFromDLL(libFileName,ppTestCOM,ppContext);
免费(libFileName);
}
返回hrRet;
}
我还使用WOW64版本的regedit检查了注册表,从那里看,
HKEY_CLASSES\u ROOT
HKEY_CURRENT\u USER\Software\CLASSES
都很好


编辑以添加:我使用的是Windows 7,而不是XP/Vista。根据,这是一个重要的区别。

您可以尝试SysInternals的PROCMON工具来检查使用了哪些注册表项。您还可以使用.exe进行筛选,以帮助缩小范围。Regsvr32不会写入HKCU,而是写入HKLM。COM不像您那样使用HKCR别名,它首先在HKCU中显示,然后在HKLM中显示。添加注册表重定向程序以使其混乱;)是的,使用ProcMon查看实际发生的情况。