从变体VT_UNKNOWN中读取和显示数据

时间:2017-02-26 23:08:17

标签: c++ com wmi variant wmi-query

我希望在打开时检索每个进程的信息。而不只是编写一个“哑”循环,只是迭代所有打开的进程,并检查什么时候发生了变化,我想做一些更优雅的事情。 我想查询进程的创建事件,并从事件中检索有关进程的信息,如下所示: 我使用WMI以异步方式查询Win32_Process实例的__InstanceCreationEvent,如下所示:

hr = pSvc->ExecNotificationQueryAsync(
            _bstr_t("WQL"),
            _bstr_t("SELECT * "
                "FROM __InstanceCreationEvent WITHIN 1 "
                "WHERE TargetInstance ISA 'Win32_Process'"),
            WBEM_FLAG_SEND_STATUS,
            NULL,
            pStubSink);

ExecNotificationQueryAsync检索事件时,它会调用用户对IWbemObjectSink::Indicate方法的实现,并将事件作为IWbemClassObject接口传递给它。 (它传递指向所有这些事件的数组的指针)。 现在这是问题所在。我使用IWbemClassObject::Get来获取TargetInstance属性(即Win32_Process实例)中的数据。但是,Get函数会将结果输出到VARIANT。检查结构的vt成员时,我发现包含有效数据的成员是punkVal。 punkVal的类型是IUnknown。 基本上我的问题如下: 如何通过Win32_Process获取punkVal个实例? 这是我对Indicate方法的实现:

HRESULT EventSink::Indicate(LONG lObjectCount,
IWbemClassObject **apObjArray)
{

    for (int i = 0; i < lObjectCount; i++)
    {
        IWbemClassObject * InstanceCreationEventInterface = apObjArray[i];

        VARIANT v;
        BSTR strClassProp = SysAllocString(L"TargetInstance");
        HRESULT hr;
        hr = InstanceCreationEventInterface->Get(strClassProp, 0, &v, 0, 0);
        SysFreeString(strClassProp);

        if (SUCCEEDED(hr) && (V_VT(&v) == VT_UNKNOWN))
        {
            wcout << (&v)->punkVal << endl; //How do I use punkVal here to get the Win32_Process instance?
        }
        else
        {
            wprintf(L"Error in getting specified object\n");
        }
        VariantClear(&v);
    }

    return WBEM_S_NO_ERROR;
}

由于punkVal的类型是IUnknown*,唯一可以用来检索实例的方法是IUnknown::QueryInterface但是我真的没有办法使用这种方法来获取Win32_Process实例。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

TargetInstance也是一个IWbemClassObject,因此您可以在IUnknown上为IWbemClassObject进行QI。

这里的答案在SO上证明了这一点:C++: Monitor process creation and termination in Windows