【发布时间】:2017-07-17 10:53:40
【问题描述】:
我想在每个进程打开的那一刻检索有关它的信息。我不只是编写一个“愚蠢”的循环来迭代所有打开的进程并检查什么时候发生了变化,我想做一些更优雅的事情。 我想查询进程的创建事件并从事件中检索有关进程的信息,如下所示: 我使用 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。
基本上我的问题如下:
如何通过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。stackoverflow.com/questions/28897897/…
-
@SimonMourier 谢谢,这解决了我的问题。我已经为这个问题苦恼太久了:)
标签: c++ com wmi variant wmi-query