UEZ Posted August 16, 2008 Share Posted August 16, 2008 (edited) Is it possible to get the parent process which has started my process? E.g. When I created a screensaver and rundll32.exe starts my ss in preview window then rundll32.exe is the parent process and my ss is a child process of it! Further can I get the amount of child processes which has e.g. rundll32.exe has started? <Parent process> PID 1000 (e.g. rundll32.exe) ├-----> <Child Process 1> PID 2000 ├-----> <Child Process 2> PID 2001 ├-----> <Child Process 2> PID 2002 (e.g. my program) … ├-----> <Child Process n> PID m Thanks, UEZ Edited November 8, 2010 by UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted August 16, 2008 Moderators Share Posted August 16, 2008 (edited) There's the WMI way: http://www.autoitscript.com/forum/index.ph...st&p=555530But I'm not a fan of WMI because not every PC has it running or permissions to run it.I wrote something similar in another language, I translated it to AutoIt, and with a few tests it seems it works ok. And I'm sure it's faster than WMI.expandcollapse popupMsgBox(0, "Parent Process", _ProcessGetParent(@AutoItPID)) Func _ProcessGetParent($i_pid) Local Const $TH32CS_SNAPPROCESS = 0x00000002 Local $a_tool_help = DllCall("Kernel32.dll", "long", "CreateToolhelp32Snapshot", "int", $TH32CS_SNAPPROCESS, "int", 0) If IsArray($a_tool_help) = 0 Or $a_tool_help[0] = -1 Then Return SetError(1, 0, $i_pid) Local $tagPROCESSENTRY32 = _ DllStructCreate _ ( _ "dword dwsize;" & _ "dword cntUsage;" & _ "dword th32ProcessID;" & _ "uint th32DefaultHeapID;" & _ "dword th32ModuleID;" & _ "dword cntThreads;" & _ "dword th32ParentProcessID;" & _ "long pcPriClassBase;" & _ "dword dwFlags;" & _ "char szExeFile[260]" _ ) DllStructSetData($tagPROCESSENTRY32, 1, DllStructGetSize($tagPROCESSENTRY32)) Local $p_PROCESSENTRY32 = DllStructGetPtr($tagPROCESSENTRY32) Local $a_pfirst = DllCall("Kernel32.dll", "int", "Process32First", "long", $a_tool_help[0], "ptr", $p_PROCESSENTRY32) If IsArray($a_pfirst) = 0 Then Return SetError(2, 0, $i_pid) Local $a_pnext, $i_return = 0 If DllStructGetData($tagPROCESSENTRY32, "th32ProcessID") = $i_pid Then $i_return = DllStructGetData($tagPROCESSENTRY32, "th32ParentProcessID") DllCall("Kernel32.dll", "int", "CloseHandle", "long", $a_tool_help[0]) If $i_return Then Return $i_return Return $i_pid EndIf While 1 $a_pnext = DLLCall("Kernel32.dll", "int", "Process32Next", "long", $a_tool_help[0], "ptr", $p_PROCESSENTRY32) If IsArray($a_pnext) And $a_pnext[0] = 0 Then ExitLoop If DllStructGetData($tagPROCESSENTRY32, "th32ProcessID") = $i_pid Then $i_return = DllStructGetData($tagPROCESSENTRY32, "th32ParentProcessID") If $i_return Then ExitLoop $i_return = $i_pid ExitLoop EndIf WEnd If $i_return = "" Then $i_return = $i_pid DllCall("Kernel32.dll", "int", "CloseHandle", "long", $a_tool_help[0]) Return $i_return EndFuncEdit:Had to edit code... I foresaw an issue with it. Edited August 16, 2008 by SmOke_N code would help huh? lol ... Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
UEZ Posted August 16, 2008 Author Share Posted August 16, 2008 Excellent work SmOke_N I didn't mentioned not to use WMI because of performance / security issues.What about the amount of child processes when I know now my parent process?Thanks,UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted August 16, 2008 Moderators Share Posted August 16, 2008 (edited) Excellent work SmOke_N I didn't mentioned not to use WMI because of performance / security issues. What about the amount of child processes when I know now my parent process? Thanks, UEZI was working on that as well. Without getting into a recursive nightmare, this will only get top level child processes:expandcollapse popup#include <array.au3> $a_children = _ProcessGetChildren(252) _ArrayDisplay($a_children) Func _ProcessGetChildren($i_pid) ; First level children processes only Local Const $TH32CS_SNAPPROCESS = 0x00000002 Local $a_tool_help = DllCall("Kernel32.dll", "long", "CreateToolhelp32Snapshot", "int", $TH32CS_SNAPPROCESS, "int", 0) If IsArray($a_tool_help) = 0 Or $a_tool_help[0] = -1 Then Return SetError(1, 0, $i_pid) Local $tagPROCESSENTRY32 = _ DllStructCreate _ ( _ "dword dwsize;" & _ "dword cntUsage;" & _ "dword th32ProcessID;" & _ "uint th32DefaultHeapID;" & _ "dword th32ModuleID;" & _ "dword cntThreads;" & _ "dword th32ParentProcessID;" & _ "long pcPriClassBase;" & _ "dword dwFlags;" & _ "char szExeFile[260]" _ ) DllStructSetData($tagPROCESSENTRY32, 1, DllStructGetSize($tagPROCESSENTRY32)) Local $p_PROCESSENTRY32 = DllStructGetPtr($tagPROCESSENTRY32) Local $a_pfirst = DllCall("Kernel32.dll", "int", "Process32First", "long", $a_tool_help[0], "ptr", $p_PROCESSENTRY32) If IsArray($a_pfirst) = 0 Then Return SetError(2, 0, $i_pid) Local $a_pnext, $a_children[11][2] = [[10]], $i_child_pid, $i_parent_pid, $i_add = 0 $i_child_pid = DllStructGetData($tagPROCESSENTRY32, "th32ProcessID") If $i_child_pid <> $i_pid Then $i_parent_pid = DllStructGetData($tagPROCESSENTRY32, "th32ParentProcessID") If $i_parent_pid = $i_pid Then $i_add += 1 $a_children[$i_add][0] = $i_child_pid $a_children[$i_add][1] = DllStructGetData($tagPROCESSENTRY32, "szExeFile") EndIf EndIf While 1 $a_pnext = DLLCall("Kernel32.dll", "int", "Process32Next", "long", $a_tool_help[0], "ptr", $p_PROCESSENTRY32) If IsArray($a_pnext) And $a_pnext[0] = 0 Then ExitLoop $i_child_pid = DllStructGetData($tagPROCESSENTRY32, "th32ProcessID") If $i_child_pid <> $i_pid Then $i_parent_pid = DllStructGetData($tagPROCESSENTRY32, "th32ParentProcessID") If $i_parent_pid = $i_pid Then If $i_add = $a_children[0][0] Then ReDim $a_children[$a_children[0][0] + 11][2] $a_children[0][0] = $a_children[0][0] + 10 EndIf $i_add += 1 $a_children[$i_add][0] = $i_child_pid $a_children[$i_add][1] = DllStructGetData($tagPROCESSENTRY32, "szExeFile") EndIf EndIf WEnd If $i_add <> 0 Then ReDim $a_children[$i_add + 1][2] $a_children[0][0] = $i_add EndIf DllCall("Kernel32.dll", "int", "CloseHandle", "long", $a_tool_help[0]) If $i_add Then Return $a_children Return SetError(3, 0, 0) EndFunc Edit: Turned the return into a 2 dimensional array... [n][0] will be the PID, [n][1] will be the name of the process. If no array is returned, then that process does not have child processes. Edit2: Changed ReDim $a_children[$a_children[0][0] + 10][2] to ReDim $a_children[$a_children[0][0] + 11][2] Edited August 16, 2008 by SmOke_N Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted August 16, 2008 Moderators Share Posted August 16, 2008 If you've already checked out the getting child processes, check it it now with the 2D array that includes the process name as well. Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
UEZ Posted August 16, 2008 Author Share Posted August 16, 2008 I was working on that as well.Without getting into a recursive nightmare, this will only get top level child processes:...Once again: Excellent work SmOke_N.Now my screensaver closes properly when I select in 'settings window' another ss. Screensaver.au3 uses the ComboList check to close ss in 'settings window'.My idea was that only one child process can run by rundll32.exe when selecting any ss.Thanks a lot!UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Squirrely1 Posted August 16, 2008 Share Posted August 16, 2008 (edited) Thanks SmokeN - I'll probably use it. Want to complete the order form: ; ================================================================================================== ; Name: _ProcessGetChildren ; Purpose: Get a list of top-level child processes ; Syntax: ; _ProcessGetChildren($i_ParentPID) ; Returns: ; Success: ; If child processes ARE found ... ; Returns a two-dimensional array wherein ... ; $arr[n][0] = the PID of a child process ; $arr[n][1] = the name of that child process ; ; If child processes are NOT found ... ; Returns 0 ; ; Failure: ; The passed $i_ParentPID is returned unchanged; ; @error is set as follows ... ; 1 - the first call to a function within "Kernel32.dll" failed. ; 2 - the first call to a function within "Kernel32.dll" failed. ; ; Notes: ; If successful and no array is returned, then the passed process does not have child ; processes. ; ; #Region Test_harness ; #include <array.au3> ; Global $a_children = _ProcessGetChildren(252) ; _ArrayDisplay($a_children) ; #EndRegion ; Author: ; SmokeN - August 16, 2008; Kudos to UEZ ; ================================================================================================== Like, maybe this only works in Vista + Edited August 16, 2008 by Squirrely1 Das Häschen benutzt Radar Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted August 16, 2008 Moderators Share Posted August 16, 2008 (edited) Thanks SmokeN - I'll probably use it. Want to complete the order form: expandcollapse popup; ================================================================================================== ; Name: _ProcessGetChildren ; Purpose: Get a list of top-level child processes ; Syntax: ; _ProcessGetChildren($i_ParentPID) ; Returns: ; Success: ; If child processes ARE found ... ; Returns a two-dimensional array wherein ... ; $arr[n][0] = the PID of a child process ; $arr[n][1] = the name of that child process ; ; If child processes are NOT found ... ; Returns 0 ; ; Failure: ; The passed $i_ParentPID is returned unchanged; ; @error is set as follows ... ; 1 - the first call to a function within "Kernel32.dll" failed. ; 2 - the first call to a function within "Kernel32.dll" failed. ; ; Notes: ; If successful and no array is returned, then the passed process does not have child ; processes. ; ; #Region Test_harness ; #include <array.au3> ; Global $a_children = _ProcessGetChildren(252) ; _ArrayDisplay($a_children) ; #EndRegion ; Author: ; SmokeN - August 16, 2008; Kudos to UEZ ; ==================================================================================================oÝ÷ Ûú®¢×¹Ú,笰ý§k÷®¦Ç«¾'²Öç£ÐSZØZ¶uêå¢,~éçÈGb´[§rبuêÚºÚ"µÍÏOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOBÂÈ[Ý[Û[YNÔØÙÜÑÙ]Ú[[ BÈØÜ[Û]Y]H[^HÙ[Ü][Ú[ØÙÜÙÈÈ[Y]ÊN ÌÍÚWÜYHØÙÜÈY[YYÙHØÙÜÈ[ÝHØ[ÈÝHÚ[ÈØÙÜÙÈÛHÈ][YJÊNÈÛÝXØÙÜÎÈ[Y[Ú[Û[^NÈÛVÌHÈHØÙÜÈYÙHÚ[ÈÛVÌWHÈHØÙÜÈ[YHÙHÚ[ÂÈÛZ[NÈÛ^HÂÈÜÈ JNÜX]UÛÛ[ÌÛÚÝZ[YÈ NØÙÜÌÌÝÈ]]ÜÊNÛSÚÙWÓ ÛY[Ù[HÂÏOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO Edited August 16, 2008 by SmOke_N Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
Squirrely1 Posted August 16, 2008 Share Posted August 16, 2008 (edited) I can certainly see how this one might end up in Process.au3It could probably find hidden processes - like ones left over from running those funky shareware screen savers? I see benchmarking utility is this thing, as well.Well down, thou faithful and observant service station attendant, and...Thanks again, cuz this is really Smoke_N ! I think UEZ might be a little confused about this thing though, because I don't see how it could be used to close your screensaver when you change the selection in the dropdown of the applet's Screen Saver tab when Windows closes only the GUI of your screensaver.Edit 1: Oh - I get it - keep checking, and if your .scr process is no longer the child of the rundll32.exe pid, then exit. Edited August 16, 2008 by Squirrely1 Das Häschen benutzt Radar Link to comment Share on other sites More sharing options...
UEZ Posted August 16, 2008 Author Share Posted August 16, 2008 ... Edit 1: Oh - I get it - keep checking, and if your .scr process is no longer the child of the rundll32.exe pid, then exit. That's not possible, because when you select another ss from ComboBox then rundll32.exe start the other ss and it becomes also a child process. That means that your ss must close when the amount of child processes is greater then 1. Here an extract of my ss: ... Local $parent_PID = _ProcessGetParent(@AutoItPID) Local $child_PID While 1 If Not WinExists($hWnd) Then Quit() $child_PID = _ProcessGetChildren($parent_PID) If $child_PID[0] > 1 Then Quit() ;if another screensaver is selected in ComboBox close ss Line_Color() Draw() WEnd ... UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Squirrely1 Posted August 16, 2008 Share Posted August 16, 2008 (edited) Thanks for all your attention my behalf, UEZ, but I see a few problems with your function ... #1: _ProcessGetChildren returns a two-dimensional array when it even returns an array. #2: I see nothing in the documentation for _ProcessGetChildren even that $aArray[0][0] returns the number of child processes. #3: Couldn't it be true that when some other screensaver is selected in the combo, that your screensaver's process keeps running but stops being a child, while the newly selected one begins being a child, thereby keeping the number of child processes the same? Thanks again from the USA (no that country is nowhere in China). Edited August 16, 2008 by Squirrely1 Das Häschen benutzt Radar Link to comment Share on other sites More sharing options...
UEZ Posted August 16, 2008 Author Share Posted August 16, 2008 (edited) Thanks for all your attention my behalf, UEZ, but I see a few problems with your function ... #1: _ProcessGetChildren returns a two-dimensional array when it even returns an array. #2: I see nothing in the documentation for _ProcessGetChildren even that $aArray[0][0] returns the number of child processes. #3: Couldn't it be true that when some other screensaver is selected in the combo, that your screensaver's process keeps running but stops being a child, while the newly selected one begins being a child, thereby keeping the number of child processes the same? Thanks again from the USA - no, that country is nowhere in China. Oops, I forgotten to mention that I used the versions with 1D array before it was edited. It is working: click here for scr file + source code Source code will be available when I think that it can be published Greetings from the Boot Camp near Frankfurt / Germany UEZ Edited September 15, 2009 by UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted August 16, 2008 Moderators Share Posted August 16, 2008 #2: I see nothing in the documentation for _ProcessGetChildren even that $aArray[0][0] returns the number of child processes.That's my fault, I did make [0][0] contain the number of child processes found. I was trying to keep it similar to the ProcessList() function. Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
autoItrules209 Posted September 15, 2009 Share Posted September 15, 2009 well, im not really sure, but seems like "ProcessGetChildren" does not work in Windows 7 x64 - can anyone verify? or maybe even someone already has a workaround for this? Link to comment Share on other sites More sharing options...
UEZ Posted November 12, 2009 Author Share Posted November 12, 2009 well, im not really sure, but seems like "ProcessGetChildren" does not work in Windows 7 x64 - can anyone verify? or maybe even someone already has a workaround for this? It is not running in native x64 mode (F5 in SciTE)! You have to compile and running x32 mode. expandcollapse popup#AutoIt3Wrapper_UseX64=n #include <array.au3> $explorer = ProcessList("explorer.exe") $a_children = _ProcessGetChildren($explorer[1][1]) _ArrayDisplay($a_children) Func _ProcessGetChildren($i_pid) ; First level children processes only Local Const $TH32CS_SNAPPROCESS = 0x00000002 Local $a_tool_help = DllCall("Kernel32.dll", "long", "CreateToolhelp32Snapshot", "int", $TH32CS_SNAPPROCESS, "int", 0) If IsArray($a_tool_help) = 0 Or $a_tool_help[0] = -1 Then Return SetError(1, 0, $i_pid) Local $tagPROCESSENTRY32 = _ DllStructCreate _ ( _ "dword dwsize;" & _ "dword cntUsage;" & _ "dword th32ProcessID;" & _ "uint th32DefaultHeapID;" & _ "dword th32ModuleID;" & _ "dword cntThreads;" & _ "dword th32ParentProcessID;" & _ "long pcPriClassBase;" & _ "dword dwFlags;" & _ "char szExeFile[260]" _ ) DllStructSetData($tagPROCESSENTRY32, 1, DllStructGetSize($tagPROCESSENTRY32)) Local $p_PROCESSENTRY32 = DllStructGetPtr($tagPROCESSENTRY32) Local $a_pfirst = DllCall("Kernel32.dll", "int", "Process32First", "long", $a_tool_help[0], "ptr", $p_PROCESSENTRY32) If IsArray($a_pfirst) = 0 Then Return SetError(2, 0, $i_pid) Local $a_pnext, $a_children[11][2] = [[10]], $i_child_pid, $i_parent_pid, $i_add = 0 $i_child_pid = DllStructGetData($tagPROCESSENTRY32, "th32ProcessID") If $i_child_pid <> $i_pid Then $i_parent_pid = DllStructGetData($tagPROCESSENTRY32, "th32ParentProcessID") If $i_parent_pid = $i_pid Then $i_add += 1 $a_children[$i_add][0] = $i_child_pid $a_children[$i_add][1] = DllStructGetData($tagPROCESSENTRY32, "szExeFile") EndIf EndIf While 1 $a_pnext = DLLCall("Kernel32.dll", "int", "Process32Next", "long", $a_tool_help[0], "ptr", $p_PROCESSENTRY32) If IsArray($a_pnext) And $a_pnext[0] = 0 Then ExitLoop $i_child_pid = DllStructGetData($tagPROCESSENTRY32, "th32ProcessID") If $i_child_pid <> $i_pid Then $i_parent_pid = DllStructGetData($tagPROCESSENTRY32, "th32ParentProcessID") If $i_parent_pid = $i_pid Then If $i_add = $a_children[0][0] Then ReDim $a_children[$a_children[0][0] + 11][2] $a_children[0][0] = $a_children[0][0] + 10 EndIf $i_add += 1 $a_children[$i_add][0] = $i_child_pid $a_children[$i_add][1] = DllStructGetData($tagPROCESSENTRY32, "szExeFile") EndIf EndIf WEnd If $i_add <> 0 Then ReDim $a_children[$i_add + 1][2] $a_children[0][0] = $i_add EndIf DllCall("Kernel32.dll", "int", "CloseHandle", "long", $a_tool_help[0]) If $i_add Then Return $a_children Return SetError(3, 0, 0) EndFunc UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ 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