How to resolve a OnMessage() and a ComObjGet conflict?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
kidbit
Posts: 168
Joined: 02 Oct 2013, 16:05

How to resolve a OnMessage() and a ComObjGet conflict?

23 Oct 2013, 08:09

If you run this code and connect/disconnect a flash usb drive - the script will return an error 0x8001010D - couldn't carry out the outgoing call, because the application currently handles an incoming synchronous call.
How to fix that?

Code: Select all

SetTimer, ProcessList, 1000

OnMessage(0x219, "WM_DEVICECHANGE")
return

WM_DEVICECHANGE(wp, lp)
{
    Static DBT_DEVICEARRIVAL := 0x8000, DBT_DEVICEREMOVECOMPLETE := 0x8004, DBT_DEVTYP_VOLUME := 2
    If ((wp = DBT_DEVICEARRIVAL || wp = DBT_DEVICEREMOVECOMPLETE) && NumGet(lp + 4, "UInt") = DBT_DEVTYP_VOLUME)
    {
        dbcv_unitmask := NumGet(lp+12, "UInt")
        Loop, 26    ; The number of letters in latin alphabet.
        {
            Letter := Chr(Asc("A") + A_Index - 1)
        } Until (dbcv_unitmask >> (A_Index - 1))&1
        MsgBox, % "Диск """ Letter ":"" " (wp = DBT_DEVICEARRIVAL ? "подключен" : "отключен")
    }
}

ProcessList:
    For Process In ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process")
        indexProcesses++
Return
question := (2b) || !(2b) © Shakespeare.
HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: How to resolve a OnMessage() and a ComObjGet conflict?

23 Oct 2013, 08:15

I think you have to split the tasks into 2 processes or don't use COM but EnumProcesses.
kidbit
Posts: 168
Joined: 02 Oct 2013, 16:05

Re: How to resolve a OnMessage() and a ComObjGet conflict?

23 Oct 2013, 08:20

Thanks for your reply.
Well, I can't afford running more than 1 process.
Would you be so kind to provide an example of the use of EnumProcesses? I'm still quite newb to translating WinAPI syntax to AHK calls to WinAPI functions.
question := (2b) || !(2b) © Shakespeare.
HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: How to resolve a OnMessage() and a ComObjGet conflict?

23 Oct 2013, 08:39

Sure ;)

Code: Select all

MsgBox % ProcessCount()
ProcessCount(){
	static proc,init:=VarSetCapacity(proc,1024*4)
	If InStr( ",WIN_NT4,WIN_95,WIN_98,WIN_ME,WIN_XP,WIN_2003," , "," A_OSVersion ",")
		DllCall("psapi\EnumProcesses","PTR",&proc,"UInt",1024,"UInt*",pBytesReturned)
	else DllCall("K32EnumProcesses","PTR",&proc,"UInt",1024,"UInt*",pBytesReturned)
	return pBytesReturned//4
}
kidbit
Posts: 168
Joined: 02 Oct 2013, 16:05

Re: How to resolve a OnMessage() and a ComObjGet conflict?

23 Oct 2013, 08:50

Thanks for the code, but seems like I explained the problem poorly. I should have provided more code from my script.

Code: Select all

ProcessList:
	Global processesSnapshot := [], Global scriptsSnapshot := [], Global indexScripts := 0, Global indexProcesses := 0
	For Process In ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process")	; Parsing through a list of running processes to filter out non-ahk ones (filters are based on "If RegExMatch" rules).
	{	; A list of accessible parameters related to the running processes: http://msdn.microsoft.com/en-us/library/windows/desktop/aa394372%28v=vs.85%29.aspx
		indexProcesses++
		processesSnapshot[indexProcesses, "pid"] := Process.ProcessId ; Fulfilling the array processesSnapshot with processes' PIDs
		processesSnapshot[indexProcesses, "exe"] := Process.ExecutablePath ; Fulfulling the array processesSnapshot with processes executables' paths.
		; processesSnapshot[indexProcesses, "cmd"] := Process.CommandLine
		If (RegExMatch(Process.CommandLine, "Si)^(""|\s)*\Q" A_AhkPath "\E.*\\(?<Name>.*\.ahk)(""|\s)*$", script)) && (RegExMatch(Process.CommandLine, "Si)^(""|\s)*\Q" A_AhkPath "\E.*""(?<Path>.*\.ahk)(""|\s)*$", script))
		{
			indexScripts++
			scriptsSnapshot[indexScripts, "pid"] := Process.ProcessId	; Using "ProcessId" param to fulfill our "pidsArray" array.
			scriptsSnapshot[indexScripts, "name"] := scriptName	; The first RegExMatch outputs to "scriptName" variable, who's contents we use to fulfill our "scriptNamesArray" array.
			scriptsSnapshot[indexScripts, "path"] := scriptPath	; The second RegExMatch outputs to "scriptPath" variable, who's contents we use to fulfill our "scriptPathArray" array.
		}
	}
Return
That function of yours seems to just retrieve the total number of running processes upon calling it, and I need to gather per-process info into an array or an Object (but I don't know how to work with objects) to save these data for later parsing.
question := (2b) || !(2b) © Shakespeare.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Bing [Bot], feiy, hitman, mikeyww and 127 guests