This is a test code created to test the new dispatch class implementation. It acquires process creation events from WMI, but fails to query process name, and even the number of properties (EDIT: does not work with INT, but UINT).
Can anyone modify OnObjectReady method to display process name, or something else from Win32_Process ?
' WMI notifications example - IDispatch implementation test
' compile for console
$if exists("stdafx.inc")
$include "stdafx.inc" ' content: $include "wbemdisp.inc"
$else
$include "wbemdisp.inc"
$endif
class CSWbemSinkEvents implements ISWbemSinkEvents
' uses CIWBasicBaseUnknownClass and CIWBasicBaseDispatchClass
endclass
'===============================
CoInitializeEx(0, COINIT_MULTITHREADED)
print "getting WMI object..."
IDispatch wmiSvc = GetComObject(0, "winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\cimv2")
if (wmiSvc)
print "creating SWbemSink..."
IDispatch MySink = CreateComObject("WbemScripting.SWbemSink")
if (MySink)
print "creating CSWbemSinkEvents..."
pointer sink = new CSWbemSinkEvents
print "advising events"
*sink.Advise(MySink)
print "executing asynchronous query..."
wmiSvc.ExecNotificationQueryAsync(MySink, L"SELECT * FROM __InstanceCreationEvent WITHIN" _
" .1 WHERE TargetInstance ISA 'Win32_Process'")', "WQL", wbemFlagSendStatus)
int a
INPUT "Waiting for new process creation events.\nPress ENTER to quit\n\n",a
print "cleanup"
MySink.Cancel()
*sink.Unadvise()
*sink.Release()
MySink->Release()
endif
wmiSvc->Release()
endif
CoUninitialize()
'===============================
sub CSWbemSinkEvents::OnObjectReady(ISWbemObject objWbemObject, ISWbemNamedValueSet objWbemAsyncContext),HRESULT
COLOR 11,0
print "OnObjectReady"
COLOR 7,0
ISWbemPropertySet properties = objWbemObject.Properties_
if (properties)
uint count = properties.Count
print " - properties ok: Count=",count
ISWbemProperty property = properties.Item("Name")
if (property)
print " - property ok"
BSTR bstrName = properties.Value
if (bstrName)
print *<wstring>bstrName
SysFreeString(bstrName)
endif
property->Release()
endif
properties->Release()
endif
return 1
endsub
' optional methods - never called, can be deleted.
sub CSWbemSinkEvents::OnCompleted(WbemErrorEnum iHResult, ISWbemObject objWbemErrorObject, ISWbemNamedValueSet objWbemAsyncContext),HRESULT
print "OnCompleted: WbemErrorEnum=0x",HEX$(static_cast(uint,iHResult))
return 0
endsub
sub CSWbemSinkEvents::OnProgress(long iUpperBound, long iCurrent, BSTR strMessage, ISWbemNamedValueSet objWbemAsyncContext),HRESULT
print "OnProgress"
return 0
endsub
sub CSWbemSinkEvents::OnObjectPut(ISWbemObjectPath objWbemObjectPath, ISWbemNamedValueSet objWbemAsyncContext),HRESULT
print "OnObjectPut"
return 0
endsub
Just got it working - had to append .TargetInstance after objWbemObject:
sub CSWbemSinkEvents::OnObjectReady(ISWbemObject objWbemObject, ISWbemNamedValueSet objWbemAsyncContext),HRESULT
COLOR 11,0
print "OnObjectReady"
COLOR 7,0
BSTR bstrName, bstrValue
ISWbemProperty property
bstrName = objWbemObject.TargetInstance.Name
if (bstrName)
print *<wstring>bstrName
SysFreeString(bstrName)
endif
ISWbemPropertySet properties = objWbemObject.TargetInstance.Properties_
if (properties)
uint count = properties.Count
print " - properties ok: Count=",count
$ifdef show_all_properties
IUnknown unkenum = properties._NewEnum
if (unkenum)
print " - get__NewEnum ok"
IEnumVARIANT v
if (!unkenum->QueryInterface(_IID_IEnumVARIANT, &v))
print " - IEnumVARIANT ok"
for property = each v
bstrName = property.Name
bstrValue = property.Value
if (bstrName && bstrValue)
print *<wstring>bstrName, "\t=", *<wstring>bstrValue
endif
if (bstrValue) then SysFreeString(bstrValue)
if (bstrName) then SysFreeString(bstrName)
next
v->Release()
endif
unkenum->Release()
endif
$else
property = properties.Item("Name")
if (property)
print " - property ok"
bstrName = property.Value
if (bstrName)
print *<wstring>bstrName
SysFreeString(bstrName)
endif
property->Release()
endif
$endif
properties->Release()
endif
return 0
endsub