我希望在打开时检索每个进程的信息。而不只是编写一个“哑”循环,只是迭代所有打开的进程,并检查什么时候发生了变化,我想做一些更优雅的事情。 我想查询进程的创建事件,并从事件中检索有关进程的信息,如下所示: 我使用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实例。
非常感谢任何帮助。
答案 0 :(得分:1)
TargetInstance也是一个IWbemClassObject,因此您可以在IUnknown上为IWbemClassObject进行QI。
这里的答案在SO上证明了这一点:C++: Monitor process creation and termination in Windows