来自IWbemClassObject :: Get的未知异常

时间:2016-10-20 00:10:20

标签: c++ exception-handling wmi wbem

我正在尝试在持久化后从WMI对象中检索“ID”。

在构建实例后,我坚持这样:

hRes = pSvc->PutInstance(pNewInstance, 0, pCtx, &pResult);

一切都很好和花花公子 - 它进入了WMI。然后,我使用我的pResult IWbemCallResult **ppCallResult来调用IWbemCallResult::GetResultObject,如下所示:

IWbemClassObject *ppResultObject = NULL;
hRes = pResult->GetResultObject(WBEM_INFINITE, &ppResultObject);

大。 hResS_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

如果我将它全部包装在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;
    }

1 个答案:

答案 0 :(得分:0)

我通过更改

解决了这个问题
hRes = pCallRes->GetResultObject(WBEM_INFINITE, &objPtr);

BSTR objPath = NULL;
hRes = pCallRes->GetResultString(WBEM_INFINITE, &objPath);
...
hRes = pWbemServices->GetObject(objPath, 0, NULL, &objPtr, NULL);

在{/ p>中制作了vnt

hRes = objPtr->Get(L"ID", 0, &vnt, NULL, NULL);

不是0

在实例持续存在之前,似乎已经对实例进行了一些处理,因此正在检索的result object没有“准备好”。当我GetResultString并根据该对象路径重新获取对象时,它具有可用的值。去图。