anonymous1184
anonymous1184

Reputation: 98

Monitor spawned processes (process tree) from AHK

I've been serching (search engine, SO, AHK forums) without success how to get the PIDs of the hierarchy tree of anything ran by Run[Wait] command.

Any help/directiono will be highly appreciated.

Upvotes: 1

Views: 294

Answers (1)

anonymous1184
anonymous1184

Reputation: 98

With 20 iterations looking for a 30-child process tree my average times were:

  • DLL: 0.2587435
  • WMI: 0.1113015

Here's the bench:

pid := 7880
loops := 20

time_dll := 0
Loop, % loops
{
    QPC(1)
    tree_dll := processTree(pid)
    time_dll += QPC()
}
time_dll /= loops

time_wmi := 0
Loop, % loops
{
    QPC(1)
    tree_wmi := processTree(pid, True)
    time_wmi += QPC()
}
time_wmi /= loops

MsgBox,,>, % "DLL: " time_dll "`nWMI: " time_wmi

;-------------------------------------------------------------------------------

processTree(pid, wmi := False, obj := False)
{
    Local
    tree := []
    If wmi
    {
        If !obj
            obj := ComObjGet("winmgmts:").ExecQuery("SELECT ProcessId,ParentProcessId FROM Win32_Process")
        tree := []
        For result in obj
            If pid = result.ParentProcessId
            {
                tree.Push(result.ProcessId)
                subs := %A_ThisFunc%(result.ProcessId, True, obj)
                For idx,val in subs
                    tree.Push(val)
            }
    }
    Else
    {
        Static MAX_PATH := 260 << !!A_IsUnicode
        Static varCapacity := MAX_PATH
        VarSetCapacity(lppe, varCapacity)
        NumPut(varCapacity, lppe, "UInt")
        hSnapshot := DllCall("CreateToolhelp32Snapshot", "UInt",0x2, "UInt",pid, "Ptr")
        DllCall("Process32First", "Ptr",hSnapshot, "Ptr",&lppe)
        Loop
        {
            parent := NumGet(lppe, 16 + A_PtrSize * 2, "UInt")
            If (parent = pid)
            {
                child := NumGet(lppe, 8, "UInt")
                tree.Push(child)
                gchilds := %A_ThisFunc%(child)
                For idx,val in gchilds
                    tree.Push(val)
            }
        } Until !DllCall("Process32Next", "Ptr",hSnapshot, "Ptr",&lppe)
        DllCall("CloseHandle", "Ptr",hSnapshot)
    }
    Return, tree
}

QPC(start := 0)
{
    Static P := 0, F := 0, Q := DllCall("QueryPerformanceFrequency", "Int64P",F)
    Return !DllCall("QueryPerformanceCounter", "Int64P",Q) + (start ? (P:=Q)/F : (Q-P)/F)
}

Upvotes: 1

Related Questions