近期用wmi获取本地硬件信息时,客户反映有些机器突然获取不到了。经过检查发现是在初始化WMI环境时建立实例是失败报REGDB_E_CLASSNOTREG 即“指定的类没有在注册表中注册. 也可能是指定的dwClsContext没有注册或注册表中的服务器类型损坏”不知为何。部分机器可以通过重启WMI服务恢复。但有的机器就无效。
HRESULT CWmiInfo::InitWmi()
{
HRESULT hr;
//一、初始化COM组件
//初始化COM
hr=::CoInitializeEx(0,COINIT_MULTITHREADED);
int err=GetLastError();
CString str="";
if(err!=0)
{
str.Format("%d",err);
write_log_info2(str);
}
write_log_info2("Init Co succesee");
if (SUCCEEDED(hr) || RPC_E_CHANGED_MODE == hr)
{
//设置进程的安全级别,(调用COM组件时在初始化COM之后要调用CoInitializeSecurity设置进程安全级别,否则会被系统识别为病毒)
hr=CoInitializeSecurity(NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_PKT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE,
NULL);
if(err!=0)
{
str.Format("%d",err);
write_log_info2(str);
}
write_log_info2("Init Security succesee");
//VERIFY(SUCCEEDED(hr));
//二、创建一个WMI命名空间连接
//创建一个CLSID_WbemLocator对象
hr=CoCreateInstance(CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
(LPVOID*)&m_pWbemLoc);
//VERIFY(SUCCEEDED(hr));
if(!SUCCEEDED(hr))
{
str.Format("%x",hr);
write_log_info2(str);
// write_log_info2();
return true;
}
if(err!=0)
{
str.Format("%d",err);
write_log_info2(str);
}
write_log_info2("Init Instance succesee");
//使用m_pWbemLoc连接到"root\cimv2"并设置m_pWbemSvc的指针
try
{
hr=m_pWbemLoc->ConnectServer(CComBSTR(L"ROOT\\CIMV2"),
NULL,
NULL,
0,
NULL,
0,
0,
&m_pWbemSvc);
if(!SUCCEEDED(hr))
{
str.Format("%x",hr);
write_log_info2(str);
// write_log_info2();
return true;
}
}
catch(exception * e)
{
err=GetLastError();
if(err!=0)
{
str.Format("%d",err);
write_log_info2(str);
}
str=e->what();
write_log_info2(str);
}
write_log_info2("Conn serve succesee");
if(!SUCCEEDED(hr))
{
str.Format("%x",hr);
write_log_info2(str);
// write_log_info2();
return true;
}
//VERIFY(SUCCEEDED(hr));
//三、设置WMI连接的安全性
hr=CoSetProxyBlanket(m_pWbemSvc,
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE,
NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE);
//VERIFY(SUCCEEDED(hr));
if(!SUCCEEDED(hr))
{
str.Format("%x",hr);
write_log_info2(str);
// write_log_info2();
return true;
}
if(err!=0)
{
str.Format("%d",err);
write_log_info2(str);
}
write_log_info2("Set Proxy succesee");
}
return(hr);
}