Releasing SWbemSink

Ask for help, how to use AHK_H, etc.
ELFoglalt
Posts: 1
Joined: 04 Nov 2017, 09:49
Contact:

Releasing SWbemSink

05 Nov 2017, 08:43

I am writing an application that monitors some other processes and changes behaviour based on what is running. I can detect creation and destruction events using winmgmts just fine, however I've ran into issues with closing the script properly.

Given the following code:

Code: Select all

#Persistent	

; Get WMI service
WMIServiceObject := ComObjGet("winmgmts:")

; Create sink
ProcessCreatedSink := ComObjCreate("WbemScripting.SWbemSink")
ComObjConnect(ProcessCreatedSink, "NotifyCreate_")

; Start async query
WMIServiceObject.ExecNotificationQueryAsync(ProcessCreatedSink
    , "Select * from __InstanceCreationEvent"
    . " within " 1
    . " where TargetInstance isa 'Win32_Process'")

NotifyCreate_OnObjectReady(obj)
{
    TrayTip obj.TargetInstance.Name, "Process started"
}

Xbutton2::
#X::
    WMIServiceObject := ""
    ;ProcessCreatedSink.Cancel() ; Does not exist :(
    ProcessCreatedSink := ""
    ExitApp

ProcessNotifierExample.ahk
(609 Bytes) Downloaded 322 times
If the script closes before any notifications are created, the script exits regularly. If one closes the AHK script after any notifications are created, it appears to close (icon disappears, hotkeyes stop registering), but the process actually stays in limbo, idling, until killed from the outside.
I'm fairly certain that the problem is related to the sink, not being deleted/the async call not being cancelled. But the returned COM wrapper does not seem to have any Cancel (https://msdn.microsoft.com/hu-hu/library/aa393878.aspx) like methods, and it seems like I would need something along the lines of CancelAsyncCall (https://msdn.microsoft.com/en-us/librar ... s.85).aspx), but I'm new to using windows dll-s and can't quite figure out 1. what the proper library/function call would be, 2. how to get a pointer to the actual object as opposed to the AKH wrapper returned by ComObjGet.

For anyone interested, I have a workaround for now that obviously closes the process, but I'd rather have a programatically correct solution, as I'd prefer if my notifier could be stopped and started as needed.

Code: Select all

OnExit "QuitApp" 1

ForceQuit()
{
    ProcessClose(DllCall("GetCurrentProcessId"))
}
tester
Posts: 84
Joined: 10 Jun 2021, 23:03

Re: Releasing SWbemSink

25 Sep 2022, 01:49

ELFoglalt wrote:
05 Nov 2017, 08:43

Code: Select all

    ;ProcessCreatedSink.Cancel() ; Does not exist :(
In my environment, Window 10 64bit, AutoHotkey 1.1.34.04 (I'm not using AutoHotkey_H), the Cancel() method seem to exist. When I change the method name to Cancel2() or something, an error appears but not with Cancel(). If I run your posted code, WmiPrvSE.exe starts consuming CPU like about 1%. If the script exits, the consumption stops. Also, the below line properly stops the CPU usage by pressing esc.

Code: Select all

~Esc::ProcessCreatedSink.Cancel()
So it seems to do the job.

Return to “Ask for Help”

Who is online

Users browsing this forum: No registered users and 2 guests