从变体 VT_UNKNOWN 中读取和显示数据
Read and display data from variant VT_UNKNOWN
我想在每个进程打开时检索有关它的信息。我不想只编写一个 "dumb" 循环来遍历所有打开的进程并检查何时发生变化,我想做一些更优雅的事情。
我想查询进程的创建事件并从这样的事件中检索有关进程的信息:
我使用 WMI 异步查询 __InstanceCreationEvent 个 Win32_Process 个实例,如下所示:
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
。
基本上我的问题如下:
如何通过punkVal
获取Win32_Process
实例?
这是我对 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实例.
如有任何帮助,我们将不胜感激。
TargetInstance 也是一个 IWbemClassObject,因此您可以在您拥有的 IUnknown 上对 IWbemClassObject 进行 QI。
SO 上的这个答案证明了这一点:
我想在每个进程打开时检索有关它的信息。我不想只编写一个 "dumb" 循环来遍历所有打开的进程并检查何时发生变化,我想做一些更优雅的事情。 我想查询进程的创建事件并从这样的事件中检索有关进程的信息: 我使用 WMI 异步查询 __InstanceCreationEvent 个 Win32_Process 个实例,如下所示:
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
。
基本上我的问题如下:
如何通过punkVal
获取Win32_Process
实例?
这是我对 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实例.
如有任何帮助,我们将不胜感激。
TargetInstance 也是一个 IWbemClassObject,因此您可以在您拥有的 IUnknown 上对 IWbemClassObject 进行 QI。
SO 上的这个答案证明了这一点: