Sign in to follow this  
Followers 0
Shub9561

Getting Ancestor of a Process

6 posts in this topic

#1 ·  Posted (edited)

Hey,

  I m Shian,I am trying to catch the parent and child id of a process and their names if any any error comes in my app.(By Default It will be handled by Microsoft as i m using it's product for developing applications).

For Example:-

I have created an window application by which i throw some error but now whenever an error occurs it shows me a popup.So I want to use auto scripting for getting the Parent Id,Grand Parent Id of that Child Window(Error window) and the name of the process . So that i can put any condition for working according to the Id's.

I have attached my sample code as well Please Go Through it.  

 

Edited by Shub9561

Share this post


Link to post
Share on other sites



I do not see your code, can you please post it using the code button on the toolbar. It looks like this, <>.

Otherwise, welcome to the AutoIt forum Shub9561! ^_^


Snips & Scripts


My Snips: graphCPUTemp ~ getENVvars
My Scripts: Short-Order Encrypter - message and file encryption V1.6.1 ~ AuPad - Notepad written entirely in AutoIt V1.9.4

Feel free to use any of my code for your own use.                                                                                                                                                           Forum FAQ

 

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Here is Auto It Script Code 

#include <ScreenCapture.au3>
#include <Array.au3>
#include <Date.au3>
#include <process.au3>
;#include <../includes/tsp_email.au3>


Global $log_results = ""
Global $hWnd
Global $GA_ROOT
Global $GA_PARENT
Global $GA_ROOTOWNER
Global $PID
Global $dir_name
Global $nameparent
Global $namechild
$screen_capture_directory = @DesktopDir & "\error-screenshots\"
$error_title = "Microsoft .NET Framework"
$error_window = ""
$log_file = @DesktopDir & "\c++_error_"&@IPAddress1&".log"
$success_recipients = ""

$failure_recipients = ""


If WinExists($error_title, $error_window) Then
    $log = FileOpen($log_file, 1)
    _log($log, "Checking "&@ComputerName&" ("&@IPAddress1&") at "&_NowCalc())
    _log($log, "C++ Error detected at "&_NowCalc())

    $image_file_before = _ScreenCapture($screen_capture_directory)

    WinActivate($error_title, $error_window)

    WinClose($error_title, $error_window)

 ConsoleWrite("getting param" & " = " & myroot() & @CRLF) ;
 ConsoleWrite("getting param" & " = " & _ProcessGetChildren() & @CRLF) ;

    Sleep(5000)
    If FileExists($image_file_before) Then
        _log($log, "Attempting to take screenshot")
        _log($log, "Screenshot successful")
        _log($log, "Attempting to close window")
        $image_file_after = _ScreenCapture($screen_capture_directory)
        $image_files = $image_file_before&";"&$image_file_after
    Else
        _log($log, "Attempting to take screenshot.")
        _log($log, "Screenshot not successful")
        _log($log, "Attempting to close window.")
        $image_files = ""
    EndIf

    $success = False
    If WinExists($error_title, $error_window) Then
        _log($log, "Unable to close window")
        $subject = "C++ Error Detected but NOT Cleared on "&@ComputerName&" ("&@IPAddress1&")"
    Else
        $success = True
        _log($log, "Successfully closed window")
        $subject = "C++ Error Detected and Cleared on "&@ComputerName&" ("&@IPAddress1&")"
    EndIf

    If $success = True Then
        ;$email_result = _Email_SendGrid($subject, $log_results, $success_recipients, "", "", "", "High", "", $image_files)
    Else
        ;$email_result = _Email_SendGrid($subject, $log_results, $failure_recipients, "", "", "", "High", "", $image_files)
    EndIf

    ;_log($log, "Sending email")
    ;_log($log, "Email result = "&$email_result)
    ;If Int($email_result) = 0 Then
        ;_log($log, "Email sent successfully "&_NowCalc())
    ;Else
        ;_log($log, "Email send attempt failed at "&_NowCalc())
    ;EndIf
    ;_log($log, "************************************************")
EndIf

Func _log($log_handle, $line)
    $log_results &= $line&"<br/>"
    ConsoleWrite($line&@CRLF)
    FileWriteLine($log_handle, $line)
EndFunc

Func _ScreenCapture($capture_dir)
    If Not FileExists($capture_dir&"001.jpg") Then
        ;$cur_file = 1
        DirCreate($capture_dir)
    Else
        ;$cur_dir_files = _FileListToArray($capture_dir, "*.jpg", 0)
        If @error > 0 Then
            ;$cur_file = 1
        Else
            ;$file_count = $cur_dir_files[0]
            ;Dim $cur_files[$file_count + 1][2]
            ;$cur_files[0][0] = $file_count

            ;For $f = 1 To $file_count
                ;$cur_files[$f][0] = $cur_dir_files[$f]
                ;$cur_files[$f][1] = FileGetTime($capture_dir & $cur_files[$f][0], 0, 1)
;           Next
            ;_ArraySort($cur_files, 1, 1, 0, 1)

        ;$cur_file = Int(StringTrimRight($cur_files[1][0], 4)) ;integer name of the most recently modified file
        Local $cur_file=""
            If $cur_file = 100 Then
                $cur_file = 1
            Else
                $cur_file += 1
            EndIf
        EndIf
    EndIf

    If $cur_file < 10 Then
        $cur_file = "00" & $cur_file
    ElseIf $cur_file < 100 Then
        $cur_file = "0" & $cur_file
    EndIf

    $image_file = $capture_dir & $cur_file & ".jpg"
    _ScreenCapture_Capture($image_file, 0, 0, -1, -1, False)

    Return $image_file
EndFunc   ;==>_ScreenCapture



;Functin to get the parent Id and the handler of the window for geeting data in Machine Language
Func myroot()
    Local $hWnd, $hParent, $hrootowner,$hroot
    $hWnd = GUICreate("test")
    $hrootowner = _WinAPI_GetAncestor($hWnd, $GA_ROOTOWNER) ;Provide Root Owner
       $hroot = _WinAPI_GetAncestor($hWnd, $GA_ROOT);Provide Root
          $hParent = _WinAPI_GetAncestor($hWnd, $GA_PARENT) ; Provide Parent
$hname=_ProcessGetName($hParent)
$dir = @ScriptFullPath
$name= @ScriptName
$testname= @AutoItExe
 Local $aProcessList = ProcessList("explorer.exe")
  For $i = 1 To $aProcessList[0][0]
        MsgBox($MB_SYSTEMMODAL, "", $aProcessList[$i][0] & @CRLF & "PID: " & $aProcessList[$i][1])
    Next
$dir_name= StringLeft($name,StringInStr($dir,"\",0,-1)-1)
    MsgBox($MB_SYSTEMMODAL, "Parent", "My Parent is" & $hWnd & ": " & $hParent)
    MsgBox($MB_SYSTEMMODAL, "root", "My root is " & $hWnd  & ": " & $hroot)
     MsgBox($MB_SYSTEMMODAL, "rootowner", "My rootowner is " & $hWnd & ": " & $hrootowner)
     ; MsgBox(0,"",$dir_name)

EndFunc
;Function END

;Another Function For Getting Parent Id and Child Id Of window For getting Data in User Language
;Function Starts From Here
$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

;Message Boxes for Printing Data
    EndIf
    MsgBox(0,"parent id is org",$i_parent_pid)
    MsgBox(0,"Parent org name is",_ProcessGetName ($i_parent_pid))
    MsgBox(0,"parent id after one excecution",$i_pid)
    MsgBox(0,"Parent name after one excecution",_ProcessGetName ($i_pid))
    MsgBox(0,"child id is",$i_child_pid)
    MsgBox(0,"child name  is",_ProcessGetName ($i_child_pid))
    DllCall("Kernel32.dll", "int", "CloseHandle", "long", $a_tool_help[0])
    If $i_add Then Return $a_children
    Return SetError(3, 0, 0)
EndFunc

 

 

WindowsApp.exe

Edited by Shub9561

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

You can use 

_WinAPI_GetParentProcess

to get the parent PID. If you got the parent PID then call the function again until the return value is 0.

 

You can easily create a recursive function to do this.

 

Something like this here:

#include <Array.au3>
#include <WinAPIProc.au3>

Global $iPID = @AutoItPID

$aResults = _WinAPI_GetParentProcessRec($iPID)
_ArrayDisplay($aResults, "Parent and higher PIDs of " & $iPID, "", 0, Default, "PID|Process Name")

$aResults = _WinAPI_GetParentProcessIter($iPID)
_ArrayDisplay($aResults, "Parent and higher PIDs of " & $iPID, "", 0, Default, "PID|Process Name")

Func _WinAPI_GetParentProcessRec($iPID, $bRec = True) ;coded by UEZ build 2015-04-29
    Local Static $aPIDs[20][2], $i = 1
    Local $iParent_PID = _WinAPI_GetParentProcess($iPID)
    If $iParent_PID > 0 Then
        $aPIDs[$i][0] = $iParent_PID
        $aPIDs[$i][1] = _WinAPI_GetProcessName($iParent_PID)
        $i += 1
        If $bRec Then _WinAPI_GetParentProcessRec($iParent_PID)
    EndIf
    If $i = 1 Then Return SetError(1, 0, 0)
    ReDim $aPIDs[$i - 1 * $bRec][2]
    $aPIDs[0][0] = $iPID
    $aPIDs[0][1] = _WinAPI_GetProcessName($iPID)
    Return $aPIDs
EndFunc

Func _WinAPI_GetParentProcessIter($iPID = 0, $bAll = True) ;coded by UEZ build 2015-04-30
    Local Static $aPIDs[20][2], $i = 1
    $aPIDs[0][0] = $iPID
    $aPIDs[0][1] = _WinAPI_GetProcessName($iPID)
    Local $iParent_PID = 1
    While $iParent_PID > 0
        $iParent_PID = _WinAPI_GetParentProcess($iPID)
        If @error Then ExitLoop
        $iPID = $iParent_PID
        $aPIDs[$i][0] = $iParent_PID
        $aPIDs[$i][1] = _WinAPI_GetProcessName($iParent_PID)
        $i += 1
        If Not $bAll Then ExitLoop
    WEnd
    If $i = 1 Then Return SetError(1, 0, 0)
    ReDim $aPIDs[$i - 2 * $bAll][2]
    Return $aPIDs
EndFunc

 

$aResults[0][0] is the child pid. $aResults[1][0] is its parent, $aResults[2][0] is the grandparent and so on.

Edited by UEZ
Added iterativ version
2 people like this

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

I din get why u have assigning the value of auto it Process to Global $iPID = @AutoItPID .Is there any specific reason?.

Share this post


Link to post
Share on other sites

I din get why u have assigning the value of auto it Process to Global $iPID = @AutoItPID .Is there any specific reason?.

​I'd imagine it's just for demonstration purposes.  You should be able to use any PID you want.

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0