从 AHK 监控生成的进程(进程树)
Monitor spawned processes (process tree) from AHK
我一直在搜索(搜索引擎、SO、AHK 论坛)但没有成功如何通过 Run[Wait]
命令获取任何东西的层次结构树的 PID 运行。
任何 help/directiono 将不胜感激。
通过 20 次迭代寻找 30 个子进程树,我的平均时间是:
- 动态链接库:0.2587435
- WMI:0.1113015
这是板凳:
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)
}
我一直在搜索(搜索引擎、SO、AHK 论坛)但没有成功如何通过 Run[Wait]
命令获取任何东西的层次结构树的 PID 运行。
任何 help/directiono 将不胜感激。
通过 20 次迭代寻找 30 个子进程树,我的平均时间是:
- 动态链接库:0.2587435
- WMI:0.1113015
这是板凳:
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)
}