Here's a graphical example that shows all processes and their children, but if you want to strip it down, retrieval of the process list is done just after window creation, then the CompareProcs function looks through the list to see which processes were launched by other processes in the list.
Code: Select all
; -----------------------------------------------------------------------------
; GLOBAL PROCESS LIST! Used to retrieve information after getting process list...
; -----------------------------------------------------------------------------
Global NewList Process32.PROCESSENTRY32 ()
Global ps
Global Deficon
#LIST_MODULES_ALL = $3
Procedure.s GetPath (pid)
; XP and above only! Processes on NT only return exe name by default...
If ps ; Global storing psapi.dll handle If available...
handle = OpenProcess_ (#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, 0, pid)
If handle
If CallFunction (ps, "EnumProcessModulesEx", handle, @module, 4, @needed, #LIST_MODULES_ALL)
f$ = Space (#MAX_PATH)
If CallFunction (ps, "GetModuleFileNameExA", handle, module, @f$, #MAX_PATH)
;Debug f$
EndIf
EndIf
CloseHandle_ (handle)
EndIf
EndIf
ProcedureReturn f$
EndProcedure
; This function sorts processes into TreeGadget list, so that child processes branch off from parents...
Procedure CompareProcs (gadget, currentid, currentname$, indent)
;Debug "Comparing " + currentname$ + " [" + Str (currentid) + "]"
ResetList (Process32 ())
While NextElement (Process32 ())
; Skip if checking against 'currentid', ie. same process...
If Process32 ()\th32ProcessID <> currentid
; Check currentid against this one...
againstid = Process32 ()\th32ProcessID
againstparent = Process32 ()\th32ParentProcessID
; If 'currentid' is parent of this process...
If currentid = againstparent
proc$ = PeekS (@Process32 ()\szExeFile)
indent = indent + 1
p$ = GetPath (Process32 ()\th32ProcessID)
If p$ = ""
p$ = PeekS (@Process32 ()\szExeFile)
EndIf
image = ExtractIcon_ (GetModuleHandle_ (#Null), p$, 0)
If Not image
image = Deficon
EndIf
AddGadgetItem (0, -1, p$, image, indent)
current = ListIndex (Process32 ())
CompareProcs (gadget, againstid, proc$, indent)
SelectElement (Process32 (), current)
DeleteElement (Process32 ())
indent = indent - 1
EndIf
EndIf
Wend
EndProcedure
; Window hook, used to resize/redraw TreeGadget when window is resized...
Procedure WinHook (WindowID, Message, wParam, lParam)
If Message = #WM_PAINT
ResizeGadget (0, 0, 0, WindowWidth (0), WindowHeight (0))
RedrawWindow_ (GadgetID (0), #Null, #Null, #RDW_INVALIDATE)
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
ps = OpenLibrary (#PB_Any, "psapi.dll")
; Add processes to Process32 () list...
k32 = OpenLibrary (#PB_Any, "kernel32.dll")
If k32
snap = CallFunction (k32, "CreateToolhelp32Snapshot", #TH32CS_SNAPPROCESS, 0)
If snap <> #INVALID_HANDLE_VALUE ; BUG FIX AS PER http://msdn.microsoft.com/msdnmag/issues/02/06/Debug/Default.aspx
Proc32.PROCESSENTRY32
Proc32\dwSize = SizeOf (PROCESSENTRY32)
If CallFunction (k32, "Process32First", snap, @Proc32)
AddElement (Process32 ())
CopyMemory (@Proc32, @Process32 (), SizeOf (PROCESSENTRY32))
While CallFunction (k32, "Process32Next", snap, @Proc32)
AddElement (Process32 ())
CopyMemory (@Proc32, @Process32 (), SizeOf (PROCESSENTRY32))
Wend
EndIf
CloseHandle_ (snap)
EndIf
CloseLibrary (k32)
EndIf
Deficon = LoadIcon_ (#Null, #IDI_APPLICATION)
; GUI...
OpenWindow (0, 0, 0, 800, 600, "Process list...", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
TreeGadget (0, 0, 0, WindowWidth (0), WindowHeight (0))
SetWindowCallback (@WinHook ())
; Add processes to TreeGadget...
ResetList (Process32 ())
While NextElement (Process32 ())
p$ = GetPath (Process32 ()\th32ProcessID)
If p$ = ""
p$ = PeekS (@Process32 ()\szExeFile)
EndIf
image = ExtractIcon_ (GetModuleHandle_ (#Null), p$, 0)
If Not image
image = Deficon
EndIf
AddGadgetItem (0, -1, p$, image, indent)
current = ListIndex (Process32 ())
CompareProcs (0, Process32 ()\th32ProcessID, PeekS (@Process32 ()\szExeFile), 0)
SelectElement (Process32 (), current)
Wend
For item = 0 To CountGadgetItems (0) - 1
SetGadgetItemState (0, item, #PB_Tree_Expanded)
Next
Repeat
Select WaitWindowEvent ()
Case #PB_Event_CloseWindow
Break
EndSelect
ForEver
If ps
CloseLibrary (ps)
EndIf
End