Reputation: 651
I wanted to retrieve infromation about every process the moment it opens. Instead of just writing a "dumb" loop that just iterates over all the open processes and checks when something changes, I wanted to do something more elegant. I wanted to query the creation events of processes and retrieve the information about the process from the event like this: I used WMI to asynchronously query the __InstanceCreationEvent of Win32_Process instances like this:
hr = pSvc->ExecNotificationQueryAsync(
_bstr_t("WQL"),
_bstr_t("SELECT * "
"FROM __InstanceCreationEvent WITHIN 1 "
"WHERE TargetInstance ISA 'Win32_Process'"),
WBEM_FLAG_SEND_STATUS,
NULL,
pStubSink);
When ExecNotificationQueryAsync
retrieves an event, it calls the user's implementation of the IWbemObjectSink::Indicate
method and passes it the event as a IWbemClassObject
interface. (it passes a pointer to an array of all these events).
Now here's the problem. I used IWbemClassObject::Get
in order to get the data from the TargetInstance
property (which is the Win32_Process instance). However, the Get
function outputs the result into a VARIANT
. when checking the vt
member of the structure, I found out that the member that contains the valid data is punkVal
. punkVal's type is IUnknown
.
Basically my problem is as follows:
How do I get the Win32_Process
instance through punkVal
?
this is my implementation of the Indicate
method:
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;
}
Since punkVal's type is IUnknown*
, the only method that can really be used to retrieve the instance is IUnknown::QueryInterface
however I don't really see any way to use this method to get the Win32_Process instance.
Any help would be greatly appreciated.
Upvotes: 1
Views: 1214
Reputation: 139256
TargetInstance is also a IWbemClassObject, so you can QI for IWbemClassObject on the IUnknown that you have.
This answer here on SO demonstrates this: C++: Monitor process creation and termination in Windows
Upvotes: 1