MrChiliCheese Posted May 2, 2009 Share Posted May 2, 2009 Hi guys, i know the question sounds funny, but how can i get the (grand)-grandchildren of the selection in a treeview? If figured out, that i get the childs, when using _GUICtrlTreeView_GetItemByIndex, but i don't know how to realize that... Here is my script so far... expandcollapse popup#include <GUIConstantsEx.au3> #Include <GUITreeView.au3> #Include <GUIImageList.au3> #include <Process.au3> #include <WindowsConstants.au3> #include <Array.au3> GUICreate ("test", 500,600) $process_treeview = GUICtrlCreateTreeView(5,5,490,490,BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS,$TVS_NOSCROLL)) $bn = GUICtrlCreateButton ("Child", 5,500,80,80) GUISetState () $proc_list = _ProcessListProperties() _Update() _ArrayDisplay($proc_list) While 1 $msg = GUIGetMsg () Switch $msg Case $GUI_EVENT_CLOSE Exit Case $bn MsgBox(0,"",_GetAllChildItems()) EndSwitch WEnd Exit Func _GetAllChildItems() $text = "Daddy:" & @LF & @TAB & _GUICtrlTreeView_GetText($process_treeview,_GUICtrlTreeView_GetSelection($process_treeview)) $count = _GUICtrlTreeView_GetChildCount ($process_treeview,_GUICtrlTreeView_GetSelection($process_treeview)) If $count > 0 Then $text &= @LF & @LF & "Kiddies:" For $a = 0 To $count-1 $text &= @LF & @TAB & _GUICtrlTreeView_GetText($process_treeview,_GUICtrlTreeView_GetItemByIndex ($process_treeview,_GUICtrlTreeView_GetSelection($process_treeview),$a)) Next EndIf Return $text EndFunc Func _Update() _GUICtrlTreeView_BeginUpdate($process_treeview) _GUICtrlTreeView_DeleteAll($process_treeview) For $a = 1 To $proc_list[0][0] If ProcessExists($proc_list[$a][2]) = 0 Then $last_id = _GUICtrlTreeView_Add($process_treeview, 0,$proc_list[$a][0]) $icon = _GUICtrlTreeView_SetIcon ($process_treeview,$last_id,_ProcessGetPath($proc_list[$a][1])) If $icon <> True Then _GUICtrlTreeView_SetIcon ($process_treeview,$last_id,"shell32.dll",2) EndIf Else $pPID_handle = _GUICtrlTreeView_FindItem($process_treeview, _ProcessGetName ($proc_list[$a][2])) $last_id = _GUICtrlTreeView_AddChild($process_treeview, $pPID_handle, $proc_list[$a][0]) $icon = _GUICtrlTreeView_SetIcon ($process_treeview,$last_id,_ProcessGetPath($proc_list[$a][1])) If $icon <> True Then _GUICtrlTreeView_SetIcon ($process_treeview,$last_id,"shell32.dll",2) EndIf EndIf ;~ _GUICtrlTreeView_Sort($process_treeview) Next _GUICtrlTreeView_Expand($process_treeview) _GUICtrlTreeView_EndUpdate($process_treeview) EndFunc ;=============================================================================== ; Function Name: _ProcessListProperties() ; Description: Get various properties of a process, or all processes ; Call With: _ProcessListProperties( [$Process [, $sComputer]] ) ; Parameter(s): (optional) $Process - PID or name of a process, default is "" (all) ; (optional) $sComputer - remote computer to get list from, default is local ; Requirement(s): AutoIt v3.2.4.9+ ; Return Value(s): On Success - Returns a 2D array of processes, as in ProcessList() ; with additional columns added: ; [0][0] - Number of processes listed (can be 0 if no matches found) ; [1][0] - 1st process name ; [1][1] - 1st process PID ; [1][2] - 1st process Parent PID ; [1][3] - 1st process owner ; [1][4] - 1st process priority (0 = low, 31 = high) ; [1][5] - 1st process executable path ; [1][6] - 1st process CPU usage ; [1][7] - 1st process memory usage ; [1][8] - 1st process creation date/time = "MM/DD/YYY hh:mm:ss" (hh = 00 to 23) ; [1][9] - 1st process command line string ; ... ; [n][0] thru [n][9] - last process properties ; On Failure: Returns array with [0][0] = 0 and sets @Error to non-zero (see code below) ; Author(s): PsaltyDS at http://www.autoitscript.com/forum ; Date/Version: 09/17/2008 -- v2.0.3 ; Notes: If an integer PID or string process name is provided and no match is found, ; then [0][0] = 0 and @error = 0 (not treated as an error, same as ProcessList) ; This function requires admin permissions to the target computer. ; All properties come from the Win32_Process class in WMI. ; To get time-base properties (CPU and Memory usage), a 100ms SWbemRefresher is used. ;=============================================================================== Func _ProcessListProperties($Process = "", $sComputer = ".") Local $sUserName, $sMsg, $sUserDomain, $avProcs, $dtmDate Local $avProcs[1][2] = [[0, ""]], $n = 1 ; Convert PID if passed as string If StringIsInt($Process) Then $Process = Int($Process) ; Connect to WMI and get process objects $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy, (Debug)}!\\" & $sComputer & "\root\cimv2") If IsObj($oWMI) Then ; Get collection processes from Win32_Process If $Process = "" Then ; Get all $colProcs = $oWMI.ExecQuery("select * from win32_process") ElseIf IsInt($Process) Then ; Get by PID $colProcs = $oWMI.ExecQuery("select * from win32_process where ProcessId = " & $Process) Else ; Get by Name $colProcs = $oWMI.ExecQuery("select * from win32_process where Name = '" & $Process & "'") EndIf If IsObj($colProcs) Then ; Return for no matches If $colProcs.count = 0 Then Return $avProcs ; Size the array ReDim $avProcs[$colProcs.count + 1][10] $avProcs[0][0] = UBound($avProcs) - 1 ; For each process... For $oProc In $colProcs ; [n][0] = Process name $avProcs[$n][0] = $oProc.name ; [n][1] = Process PID $avProcs[$n][1] = $oProc.ProcessId ; [n][2] = Parent PID $avProcs[$n][2] = $oProc.ParentProcessId ; [n][3] = Owner If $oProc.GetOwner($sUserName, $sUserDomain) = 0 Then $avProcs[$n][3] = $sUserDomain & "\" & $sUserName ; [n][4] = Priority $avProcs[$n][4] = $oProc.Priority ; [n][5] = Executable path $avProcs[$n][5] = $oProc.ExecutablePath ; [n][8] = Creation date/time $dtmDate = $oProc.CreationDate If $dtmDate <> "" Then ; Back referencing RegExp pattern from weaponx Local $sRegExpPatt = "\A(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(?:.*)" $dtmDate = StringRegExpReplace($dtmDate, $sRegExpPatt, "$2/$3/$1 $4:$5:$6") EndIf $avProcs[$n][8] = $dtmDate ; [n][9] = Command line string $avProcs[$n][9] = $oProc.CommandLine ; increment index $n += 1 Next Else SetError(2); Error getting process collection from WMI EndIf ; release the collection object $colProcs = 0 ; Get collection of all processes from Win32_PerfFormattedData_PerfProc_Process ; Have to use an SWbemRefresher to pull the collection, or all Perf data will be zeros Local $oRefresher = ObjCreate("WbemScripting.SWbemRefresher") $colProcs = $oRefresher.AddEnum($oWMI, "Win32_PerfFormattedData_PerfProc_Process" ).objectSet $oRefresher.Refresh ; Time delay before calling refresher Local $iTime = TimerInit() Do Sleep(20) Until TimerDiff($iTime) >= 100 $oRefresher.Refresh ; Get PerfProc data For $oProc In $colProcs ; Find it in the array For $n = 1 To $avProcs[0][0] If $avProcs[$n][1] = $oProc.IDProcess Then ; [n][6] = CPU usage $avProcs[$n][6] = $oProc.PercentProcessorTime ; [n][7] = memory usage $avProcs[$n][7] = $oProc.WorkingSet ExitLoop EndIf Next Next Else SetError(1); Error connecting to WMI EndIf ; Return array Return $avProcs EndFunc ;==>_ProcessListProperties ; #FUNCTION# =============================================================================== ; Name...........: _ProcessGetPath( ; Description ...: Retrieves a process file path ; Syntax.........: _ProcessGetPath($vProcess) ; Parameters ....: $vProcess - PID or name of a process ; Requirements...: kernel32.dll, psapi.dll ; Return values .: Success - A full process path ; @error = 0 ; Failure - Empty string ; @error = 1 - Invalid process name/PID ; @error = 2 - kernel32.dll failed to open (wrong version?) ; @error = 3 - Could not OpenProcess ; @error = 4 - psapi.dll failed to open (doesn't exist?) ; @error = 5 - returned path is empty or invalid ; Author ........: JScript, Larry, SmOke_N ; Modified.......: mrRevoked - reformated, error checking ; Remarks .......: ; Related .......: ; Link ..........; ; Example .......; ; ============================================================================================ Func _ProcessGetPath($vProcess) Local $i_PID, $hKernel32, $hPsapi, $aProcessHandle, $tDLLStruct, $iError, $sProcessPath $i_PID = ProcessExists($vProcess) If Not $i_PID Then Return SetError(1, 0, "");process doesn't exist? $hKernel32 = DllOpen("Kernel32.dll") $iError = @error If $iError Then DllClose($hKernel32) Return SetError(2, $iError, ""); dllopen kernell32.dll failed EndIf $aProcessHandle = DllCall($hKernel32, "int", "OpenProcess", "int", 0x0400 + 0x0010, "int", 0, "int", $i_PID) $iError = @error If $iError Or $aProcessHandle[0] = 0 Then DllClose($hKernel32) Return SetError(2, $iError, "");openprocess failed EndIf $hPsapi = DllOpen("Psapi.dll") $iError = @error If $iError Then DllClose($hKernel32) DllClose($hPsapi) Return SetError(3, $iError, ""); dllopen psapi.dll failed EndIf $tDLLStruct = DllStructCreate("char[1000]") DllCall($hPsapi, "long", "GetModuleFileNameEx", "int", $aProcessHandle[0], "int", 0, "ptr", DllStructGetPtr($tDLLStruct), "long", DllStructGetSize($tDLLStruct)) $iError = @error DllCall($hKernel32, "int", "CloseHandle", "int", $aProcessHandle[0]) DllClose($hKernel32) DllClose($hPsapi) If $iError Then $tDLLStruct = 0 Return SetError(4, $iError, "");getmodulefilenamex failed EndIf $sProcessPath = DllStructGetData($tDLLStruct, 1) $tDLLStruct = 0 ;format the output If StringLen($sProcessPath) < 2 Then Return SetError(5, 0, "");is empty or non readable If StringLeft($sProcessPath, 4) = "\??\" Then $sProcessPath = StringReplace($sProcessPath, "\??\", "") If StringLeft($sProcessPath, 20) = "\SystemRoot\System32" Then $sProcessPath = StringReplace($sProcessPath, "\SystemRoot\System32", @SystemDir) Return SetError(0, 0, $sProcessPath) EndFunc;==>_ProcessGetPath I hope u understand what i want and could help me thanks a lot... Link to comment Share on other sites More sharing options...
Authenticity Posted May 3, 2009 Share Posted May 3, 2009 Using recursion: expandcollapse popup#include <GUIConstantsEx.au3> #Include <GUITreeView.au3> #Include <GUIImageList.au3> #include <Process.au3> #include <WindowsConstants.au3> #include <Array.au3> GUICreate ("test", 500,600) $process_treeview = GUICtrlCreateTreeView(5,5,490,490,BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS,$TVS_NOSCROLL)) $bn = GUICtrlCreateButton ("Child", 5,500,80,80) $sStr = '' GUISetState () $proc_list = _ProcessListProperties() _Update() While 1 $msg = GUIGetMsg () Switch $msg Case $GUI_EVENT_CLOSE Exit Case $bn $sStr = '' _GetAllDescendantItems(_GUICtrlTreeView_GetSelection($process_treeview)) MsgBox(0,"", $sStr) EndSwitch WEnd Exit Func _GetAllDescendantItems($hParent) $hItem = _GUICtrlTreeView_GetFirstChild($process_treeview, $hParent) While $hItem $sStr &= _GUICtrlTreeView_GetText($process_treeview, $hItem) & @LF _GetAllDescendantItems($hItem) $hItem = _GUICtrlTreeView_GetNextChild($process_treeview, $hItem) WEnd EndFunc Func _Update() _GUICtrlTreeView_BeginUpdate($process_treeview) _GUICtrlTreeView_DeleteAll($process_treeview) For $a = 1 To $proc_list[0][0] If ProcessExists($proc_list[$a][2]) = 0 Then $last_id = _GUICtrlTreeView_Add($process_treeview, 0,$proc_list[$a][0]) $icon = _GUICtrlTreeView_SetIcon ($process_treeview,$last_id,_ProcessGetPath($proc_list[$a][1])) If $icon <> True Then _GUICtrlTreeView_SetIcon ($process_treeview,$last_id,"shell32.dll",2) EndIf Else $pPID_handle = _GUICtrlTreeView_FindItem($process_treeview, _ProcessGetName ($proc_list[$a][2])) $last_id = _GUICtrlTreeView_AddChild($process_treeview, $pPID_handle, $proc_list[$a][0]) $icon = _GUICtrlTreeView_SetIcon ($process_treeview,$last_id,_ProcessGetPath($proc_list[$a][1])) If $icon <> True Then _GUICtrlTreeView_SetIcon ($process_treeview,$last_id,"shell32.dll",2) EndIf EndIf ;~ _GUICtrlTreeView_Sort($process_treeview) Next _GUICtrlTreeView_Expand($process_treeview) _GUICtrlTreeView_EndUpdate($process_treeview) EndFunc ;=============================================================================== ; Function Name: _ProcessListProperties() ; Description: Get various properties of a process, or all processes ; Call With: _ProcessListProperties( [$Process [, $sComputer]] ) ; Parameter(s): (optional) $Process - PID or name of a process, default is "" (all) ; (optional) $sComputer - remote computer to get list from, default is local ; Requirement(s): AutoIt v3.2.4.9+ ; Return Value(s): On Success - Returns a 2D array of processes, as in ProcessList() ; with additional columns added: ; [0][0] - Number of processes listed (can be 0 if no matches found) ; [1][0] - 1st process name ; [1][1] - 1st process PID ; [1][2] - 1st process Parent PID ; [1][3] - 1st process owner ; [1][4] - 1st process priority (0 = low, 31 = high) ; [1][5] - 1st process executable path ; [1][6] - 1st process CPU usage ; [1][7] - 1st process memory usage ; [1][8] - 1st process creation date/time = "MM/DD/YYY hh:mm:ss" (hh = 00 to 23) ; [1][9] - 1st process command line string ; ... ; [n][0] thru [n][9] - last process properties ; On Failure: Returns array with [0][0] = 0 and sets @Error to non-zero (see code below) ; Author(s): PsaltyDS at http://www.autoitscript.com/forum ; Date/Version: 09/17/2008 -- v2.0.3 ; Notes: If an integer PID or string process name is provided and no match is found, ; then [0][0] = 0 and @error = 0 (not treated as an error, same as ProcessList) ; This function requires admin permissions to the target computer. ; All properties come from the Win32_Process class in WMI. ; To get time-base properties (CPU and Memory usage), a 100ms SWbemRefresher is used. ;=============================================================================== Func _ProcessListProperties($Process = "", $sComputer = ".") Local $sUserName, $sMsg, $sUserDomain, $avProcs, $dtmDate Local $avProcs[1][2] = [[0, ""]], $n = 1 ; Convert PID if passed as string If StringIsInt($Process) Then $Process = Int($Process) ; Connect to WMI and get process objects $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy, (Debug)}!\\" & $sComputer & "\root\cimv2") If IsObj($oWMI) Then ; Get collection processes from Win32_Process If $Process = "" Then ; Get all $colProcs = $oWMI.ExecQuery("select * from win32_process") ElseIf IsInt($Process) Then ; Get by PID $colProcs = $oWMI.ExecQuery("select * from win32_process where ProcessId = " & $Process) Else ; Get by Name $colProcs = $oWMI.ExecQuery("select * from win32_process where Name = '" & $Process & "'") EndIf If IsObj($colProcs) Then ; Return for no matches If $colProcs.count = 0 Then Return $avProcs ; Size the array ReDim $avProcs[$colProcs.count + 1][10] $avProcs[0][0] = UBound($avProcs) - 1 ; For each process... For $oProc In $colProcs ; [n][0] = Process name $avProcs[$n][0] = $oProc.name ; [n][1] = Process PID $avProcs[$n][1] = $oProc.ProcessId ; [n][2] = Parent PID $avProcs[$n][2] = $oProc.ParentProcessId ; [n][3] = Owner If $oProc.GetOwner($sUserName, $sUserDomain) = 0 Then $avProcs[$n][3] = $sUserDomain & "\" & $sUserName ; [n][4] = Priority $avProcs[$n][4] = $oProc.Priority ; [n][5] = Executable path $avProcs[$n][5] = $oProc.ExecutablePath ; [n][8] = Creation date/time $dtmDate = $oProc.CreationDate If $dtmDate <> "" Then ; Back referencing RegExp pattern from weaponx Local $sRegExpPatt = "\A(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(?:.*)" $dtmDate = StringRegExpReplace($dtmDate, $sRegExpPatt, "$2/$3/$1 $4:$5:$6") EndIf $avProcs[$n][8] = $dtmDate ; [n][9] = Command line string $avProcs[$n][9] = $oProc.CommandLine ; increment index $n += 1 Next Else SetError(2); Error getting process collection from WMI EndIf ; release the collection object $colProcs = 0 ; Get collection of all processes from Win32_PerfFormattedData_PerfProc_Process ; Have to use an SWbemRefresher to pull the collection, or all Perf data will be zeros Local $oRefresher = ObjCreate("WbemScripting.SWbemRefresher") $colProcs = $oRefresher.AddEnum($oWMI, "Win32_PerfFormattedData_PerfProc_Process" ).objectSet $oRefresher.Refresh ; Time delay before calling refresher Local $iTime = TimerInit() Do Sleep(20) Until TimerDiff($iTime) >= 100 $oRefresher.Refresh ; Get PerfProc data For $oProc In $colProcs ; Find it in the array For $n = 1 To $avProcs[0][0] If $avProcs[$n][1] = $oProc.IDProcess Then ; [n][6] = CPU usage $avProcs[$n][6] = $oProc.PercentProcessorTime ; [n][7] = memory usage $avProcs[$n][7] = $oProc.WorkingSet ExitLoop EndIf Next Next Else SetError(1); Error connecting to WMI EndIf ; Return array Return $avProcs EndFunc ;==>_ProcessListProperties ; #FUNCTION# =============================================================================== ; Name...........: _ProcessGetPath( ; Description ...: Retrieves a process file path ; Syntax.........: _ProcessGetPath($vProcess) ; Parameters ....: $vProcess - PID or name of a process ; Requirements...: kernel32.dll, psapi.dll ; Return values .: Success - A full process path ; @error = 0 ; Failure - Empty string ; @error = 1 - Invalid process name/PID ; @error = 2 - kernel32.dll failed to open (wrong version?) ; @error = 3 - Could not OpenProcess ; @error = 4 - psapi.dll failed to open (doesn't exist?) ; @error = 5 - returned path is empty or invalid ; Author ........: JScript, Larry, SmOke_N ; Modified.......: mrRevoked - reformated, error checking ; Remarks .......: ; Related .......: ; Link ..........; ; Example .......; ; ============================================================================================ Func _ProcessGetPath($vProcess) Local $i_PID, $hKernel32, $hPsapi, $aProcessHandle, $tDLLStruct, $iError, $sProcessPath $i_PID = ProcessExists($vProcess) If Not $i_PID Then Return SetError(1, 0, "");process doesn't exist? $hKernel32 = DllOpen("Kernel32.dll") $iError = @error If $iError Then DllClose($hKernel32) Return SetError(2, $iError, ""); dllopen kernell32.dll failed EndIf $aProcessHandle = DllCall($hKernel32, "int", "OpenProcess", "int", 0x0400 + 0x0010, "int", 0, "int", $i_PID) $iError = @error If $iError Or $aProcessHandle[0] = 0 Then DllClose($hKernel32) Return SetError(2, $iError, "");openprocess failed EndIf $hPsapi = DllOpen("Psapi.dll") $iError = @error If $iError Then DllClose($hKernel32) DllClose($hPsapi) Return SetError(3, $iError, ""); dllopen psapi.dll failed EndIf $tDLLStruct = DllStructCreate("char[1000]") DllCall($hPsapi, "long", "GetModuleFileNameEx", "int", $aProcessHandle[0], "int", 0, "ptr", DllStructGetPtr($tDLLStruct), "long", DllStructGetSize($tDLLStruct)) $iError = @error DllCall($hKernel32, "int", "CloseHandle", "int", $aProcessHandle[0]) DllClose($hKernel32) DllClose($hPsapi) If $iError Then $tDLLStruct = 0 Return SetError(4, $iError, "");getmodulefilenamex failed EndIf $sProcessPath = DllStructGetData($tDLLStruct, 1) $tDLLStruct = 0 ;format the output If StringLen($sProcessPath) < 2 Then Return SetError(5, 0, "");is empty or non readable If StringLeft($sProcessPath, 4) = "\??\" Then $sProcessPath = StringReplace($sProcessPath, "\??\", "") If StringLeft($sProcessPath, 20) = "\SystemRoot\System32" Then $sProcessPath = StringReplace($sProcessPath, "\SystemRoot\System32", @SystemDir) Return SetError(0, 0, $sProcessPath) EndFunc;==>_ProcessGetPath Link to comment Share on other sites More sharing options...
MrChiliCheese Posted May 3, 2009 Author Share Posted May 3, 2009 Thank you very much... i tried something like that, but i didn't get thtat in my mind... recursion a very cool Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now