来自 IWbemClassObject::Get 的未知异常
Unknown Exception from IWbemClassObject::Get
我试图在持久化后立即从 WMI 对象中检索 "ID"。
建立实例后,我像这样持久化它:
hRes = pSvc->PutInstance(pNewInstance, 0, pCtx, &pResult);
一切都很好——它进入了 WMI。然后我使用我的 pResult
,即 IWbemCallResult **ppCallResult
来调用 IWbemCallResult::GetResultObject
,如下所示:
IWbemClassObject *ppResultObject = NULL;
hRes = pResult->GetResultObject(WBEM_INFINITE, &ppResultObject);
太棒了。 hRes
是 S_OK
,我似乎有一个实例,我可以使用 IWbemClassObject::Get
检索属性...所以我这样做:
VARIANT v;
hRes = ppResultObject->Get(L"ID", 0, &v, 0, 0);
无论"ID"实际存在的值,VARIANT中的值为0。我设置的其他属性都取不到要么(它们也是 0)。我尝试了此代码流的无数变体,使用 ->Get(CComBSTR("ID")...
、->Get(_bstr_t("ID")...
等...
hRes
是S_OK
上这个Get too.
如果我把它全部包在一个try{}catch(...){}
里,它进入catch,但我不知道如何确定异常类型或为什么会失败。 这个逻辑或者语法有问题吗?我如何确定 Get(L"ID"...
调用出了什么问题?
这是我学习 C++ 的第 3 周。请帮助我不要那么讨厌它。
编辑:
最小、完整和可验证的示例(尽可能完整和可验证,无需访问我的机器和 WMI 连接):
bool
myNamespace::myWMIWrapper::createUser(User_t * user)
{
IWbemLocator * pIWbemLocator = NULL;
HRESULT hRes = CoCreateInstance(CLSID_WbemLocator,NULL,CLSCTX_ALL,IID_IWbemLocator, (LPVOID *) &pIWbemLocator);
if (SUCCEEDED(hRes))
{
BSTR combinedUserName = NULL;
if (m_username != NULL && m_domainname != NULL)
combinedUserName =_bstr_t(m_domainname) + _bstr_t(_T("\")) + _bstr_t(m_username);
hRes = pIWbemLocator->ConnectServer(
m_namespace, // machine name and namespace
combinedUserName, // Userid
m_password, // PW
NULL, // Locale
0, // flags
NULL, // Authority
pWCtx, // Context
&pWbemServices );
}
if (FAILED(hRes))
{
LOGGER << _T("Could not connect to the WMI server. Error code = ") << hRes ;
pIWbemLocator->Release();
pIWbemLocator = NULL;
CoUninitialize();
return false;
}
hRes = NULL;
IWbemClassObject *pNewClass = NULL;
BSTR myClassName = SysAllocString(L"My_Class");
hRes = pWbemServices->GetObject(myClassName, 0, NULL, &pNewClass, NULL);
if (FAILED(hRes))
{
LOGGER << _T("hRes failed. Couldn't find class using GetObject with class name:");
LOGGER << className;
}
SysFreeString(myClassName);
if (pNewClass == NULL) {
LOGGER << _T(" No My_Class class Object was found using query.");
return false;
}
LOGGER << _T("Class definition from WMI is found.");
IWbemClassObject *pNUser = NULL;
LOGGER << _T(" Creating an instance of My_Class.");
hRes = S_OK;
hRes = pNewClass->SpawnInstance(NULL, &pNUser);
pNewClass->Release();
if (FAILED(hRes)) {
LOGGER << _T(" My_Class Object can not be instansiated.");
return false;
}
LOGGER << _T(" Updating properties of My_Class found by WMI query");
if (user->getFirstName() != NULL) {
_variant_t v(user->getFirstName()->c_str());
LOGGER << _T(" Updating property FIRSTNAME->") << V_BSTR(&v) ;
pNuser->Put(L"FIRSTNAME", 0, &v, 0);
}
if (user->getLastName() != NULL) {
_variant_t v(user->getLastName()->c_str());
LOGGER <<_T(" Updating property LASTNAME->")<< V_BSTR(&v) ;
pNuser->Put(L"LASTNAME", 0, &v, 0);
}
LOGGER << _T(" Persisting My_Class information");
IWbemCallResult *pCallRes;
hRes = pWbemServices->PutInstance(pNuser, WBEM_FLAG_CREATE_OR_UPDATE, NULL, &pCallRes);
if (FAILED(hRes)) {
LOGGER << _T(" Persisting of the My_Class object failed.");
return false;
}
_variant_t vnt = NULL;
IWbemClassObject *objPtr = NULL;
LOGGER << _T(" calling ->GetResultObject()");
hRes = pCallRes->GetResultObject(WBEM_INFINITE, &objPtr);
if (FAILED(hRes)) {
LOGGER << _T(" calling GetResultObject failed");
return false;
}
LOGGER << _T("Calling ->Get(ID) on instance retrieved from GetResultObject.");
try {
// This line gets executed before entering catch(...)
hRes = objPtr->Get(L"ID", 0, &vnt, NULL, NULL);
}
catch (const std::exception& ex) {
LOGGER << _T(" problem with Get") << ex.what();
}
catch (...) { // I'm entering this catch block.
LOGGER << _T(" unknown exception...............");
}
return true;
}
我通过更改解决了这个问题
hRes = pCallRes->GetResultObject(WBEM_INFINITE, &objPtr);
至
BSTR objPath = NULL;
hRes = pCallRes->GetResultString(WBEM_INFINITE, &objPath);
...
hRes = pWbemServices->GetObject(objPath, 0, NULL, &objPtr, NULL);
vnt
在
hRes = objPtr->Get(L"ID", 0, &vnt, NULL, NULL);
不是 0
.
似乎在实例实际持久化之前对其进行了一些处理,因此正在检索的 result object
不是 "ready"。当我 GetResultString
并根据该对象路径重新获取对象时,它具有可用的值。去图吧。
我试图在持久化后立即从 WMI 对象中检索 "ID"。
建立实例后,我像这样持久化它:
hRes = pSvc->PutInstance(pNewInstance, 0, pCtx, &pResult);
一切都很好——它进入了 WMI。然后我使用我的 pResult
,即 IWbemCallResult **ppCallResult
来调用 IWbemCallResult::GetResultObject
,如下所示:
IWbemClassObject *ppResultObject = NULL;
hRes = pResult->GetResultObject(WBEM_INFINITE, &ppResultObject);
太棒了。 hRes
是 S_OK
,我似乎有一个实例,我可以使用 IWbemClassObject::Get
检索属性...所以我这样做:
VARIANT v;
hRes = ppResultObject->Get(L"ID", 0, &v, 0, 0);
无论"ID"实际存在的值,VARIANT中的值为0。我设置的其他属性都取不到要么(它们也是 0)。我尝试了此代码流的无数变体,使用 ->Get(CComBSTR("ID")...
、->Get(_bstr_t("ID")...
等...
hRes
是S_OK
上这个Get too.
如果我把它全部包在一个try{}catch(...){}
里,它进入catch,但我不知道如何确定异常类型或为什么会失败。 这个逻辑或者语法有问题吗?我如何确定 Get(L"ID"...
调用出了什么问题?
这是我学习 C++ 的第 3 周。请帮助我不要那么讨厌它。
编辑: 最小、完整和可验证的示例(尽可能完整和可验证,无需访问我的机器和 WMI 连接):
bool
myNamespace::myWMIWrapper::createUser(User_t * user)
{
IWbemLocator * pIWbemLocator = NULL;
HRESULT hRes = CoCreateInstance(CLSID_WbemLocator,NULL,CLSCTX_ALL,IID_IWbemLocator, (LPVOID *) &pIWbemLocator);
if (SUCCEEDED(hRes))
{
BSTR combinedUserName = NULL;
if (m_username != NULL && m_domainname != NULL)
combinedUserName =_bstr_t(m_domainname) + _bstr_t(_T("\")) + _bstr_t(m_username);
hRes = pIWbemLocator->ConnectServer(
m_namespace, // machine name and namespace
combinedUserName, // Userid
m_password, // PW
NULL, // Locale
0, // flags
NULL, // Authority
pWCtx, // Context
&pWbemServices );
}
if (FAILED(hRes))
{
LOGGER << _T("Could not connect to the WMI server. Error code = ") << hRes ;
pIWbemLocator->Release();
pIWbemLocator = NULL;
CoUninitialize();
return false;
}
hRes = NULL;
IWbemClassObject *pNewClass = NULL;
BSTR myClassName = SysAllocString(L"My_Class");
hRes = pWbemServices->GetObject(myClassName, 0, NULL, &pNewClass, NULL);
if (FAILED(hRes))
{
LOGGER << _T("hRes failed. Couldn't find class using GetObject with class name:");
LOGGER << className;
}
SysFreeString(myClassName);
if (pNewClass == NULL) {
LOGGER << _T(" No My_Class class Object was found using query.");
return false;
}
LOGGER << _T("Class definition from WMI is found.");
IWbemClassObject *pNUser = NULL;
LOGGER << _T(" Creating an instance of My_Class.");
hRes = S_OK;
hRes = pNewClass->SpawnInstance(NULL, &pNUser);
pNewClass->Release();
if (FAILED(hRes)) {
LOGGER << _T(" My_Class Object can not be instansiated.");
return false;
}
LOGGER << _T(" Updating properties of My_Class found by WMI query");
if (user->getFirstName() != NULL) {
_variant_t v(user->getFirstName()->c_str());
LOGGER << _T(" Updating property FIRSTNAME->") << V_BSTR(&v) ;
pNuser->Put(L"FIRSTNAME", 0, &v, 0);
}
if (user->getLastName() != NULL) {
_variant_t v(user->getLastName()->c_str());
LOGGER <<_T(" Updating property LASTNAME->")<< V_BSTR(&v) ;
pNuser->Put(L"LASTNAME", 0, &v, 0);
}
LOGGER << _T(" Persisting My_Class information");
IWbemCallResult *pCallRes;
hRes = pWbemServices->PutInstance(pNuser, WBEM_FLAG_CREATE_OR_UPDATE, NULL, &pCallRes);
if (FAILED(hRes)) {
LOGGER << _T(" Persisting of the My_Class object failed.");
return false;
}
_variant_t vnt = NULL;
IWbemClassObject *objPtr = NULL;
LOGGER << _T(" calling ->GetResultObject()");
hRes = pCallRes->GetResultObject(WBEM_INFINITE, &objPtr);
if (FAILED(hRes)) {
LOGGER << _T(" calling GetResultObject failed");
return false;
}
LOGGER << _T("Calling ->Get(ID) on instance retrieved from GetResultObject.");
try {
// This line gets executed before entering catch(...)
hRes = objPtr->Get(L"ID", 0, &vnt, NULL, NULL);
}
catch (const std::exception& ex) {
LOGGER << _T(" problem with Get") << ex.what();
}
catch (...) { // I'm entering this catch block.
LOGGER << _T(" unknown exception...............");
}
return true;
}
我通过更改解决了这个问题
hRes = pCallRes->GetResultObject(WBEM_INFINITE, &objPtr);
至
BSTR objPath = NULL;
hRes = pCallRes->GetResultString(WBEM_INFINITE, &objPath);
...
hRes = pWbemServices->GetObject(objPath, 0, NULL, &objPtr, NULL);
vnt
在
hRes = objPtr->Get(L"ID", 0, &vnt, NULL, NULL);
不是 0
.
似乎在实例实际持久化之前对其进行了一些处理,因此正在检索的 result object
不是 "ready"。当我 GetResultString
并根据该对象路径重新获取对象时,它具有可用的值。去图吧。