Sign in to follow this  
Followers 0
LWC

Getting a window handle from PID for more advanced programs

6 posts in this topic

I know it was discussed before, but the Wiki supposedly has an official solution to "How can I get a window handle when all I have is a PID?". Alas, it doesn't seem to work for anything more complicated than Notepad.

It completely fails, for example, with IE & Firefox (even with "-new-window URL").

In addition, if you try to run multiple instances of the same program, than it fails with programs such as Chrome (i.e. it only works on the first instance).

I've tried the various alternative unofficial forum versions as well, to no avail.

The reason why it's so important is, for example, launching a browser with multiple resolutions.

Thanks!

Share this post


Link to post
Share on other sites



I do this with '?do=embed' frameborder='0' data-embedContent>>in the function _UIA_StartSUT you can find some logic

$oSUT=_UIA_getObjectByFindAll($oDesktop, "processid:=" & $result2, $treescope_children)


 

func _UIA_StartSUT($SUT_VAR)
    local $fullName=_UIA_getVar( $SUT_VAR & ".Fullname")
    local $processName=_UIA_getVar($SUT_VAR & ".processname")
    local $app2Start=$fullName & " " & _UIA_getVar($SUT_VAR & ".Parameters")
    local $workingDir= _UIA_getVar($SUT_VAR & ".Workingdir")
    local $windowState=_UIA_getVar($SUT_VAR & ".Windowstate")
    local $result, $result2   ; Holds the process id's

;~  _UIA_Debug("SUT 1 Starting : " & $fullName & @CRLF)
    if fileexists($fullName) Then
;~      _UIA_Debug("SUT 2 Starting : " & $fullName & @CRLF)
;~      Only start new instance when not found
        $result2=processexists($processName)
        if $result2=0 Then
            _UIA_Debug("Starting : " & $app2Start & " from " & $workingDir)
            $result=run($app2Start,$workingDir, $windowState )
            $result2=ProcessWait($processName,60)
;~          sleep(500) ;~ Just to give the system some time to show everything
        EndIf

;~ Wait for the window to be there
        $oSUT=_UIA_getObjectByFindAll($oDesktop, "processid:=" & $result2, $treescope_children)
        if not isobj($oSUT) Then
            _UIA_Debug("No window found in SUT : " & $app2Start & " from " & $workingDir)
        Else
        ;~ Add it to the Runtime Type Information
            _UIA_setVar("RTI." & $SUT_VAR & ".PID", $result2)
            _UIA_setVar("RTI." & $SUT_VAR & ".HWND", hex(_UIA_getPropertyValue($oSUT, $UIA_NativeWindowHandlePropertyId)))
;~          _UIA_DumpThemAll($oSUT,$treescope_subtree)
        EndIf
    Else
        _UIA_Debug("No clue where to find the system under test (SUT) on your system, please start manually:" & @CRLF )
        _UIA_Debug($app2Start & @CRLF)
    EndIf
EndFunc

Share this post


Link to post
Share on other sites

I would use the second option >>


_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 04/09/2015

Share this post


Link to post
Share on other sites

Unfortunately, the second option (which, BTW, was moved to require WinAPIProc.au3 nowadays) didn't do the job for me.

junkew's solution would require more research.

Share this post


Link to post
Share on other sites

OK. Good luck.


_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 04/09/2015

Share this post


Link to post
Share on other sites

Yo guise, this works (Tested just now, just posting this incase anyone else had the same problem

 
Func _GetHwndFromPID($PID)
    $hWnd = 0
    $stPID = DllStructCreate("int")
    Do
        $winlist2 = WinList()
        For $i = 1 To $winlist2[0][0]
            If $winlist2[$i][0] <> "" Then
                DllCall("user32.dll", "int", "GetWindowThreadProcessId", "hwnd", $winlist2[$i][1], "ptr", DllStructGetPtr($stPID))
                If DllStructGetData($stPID, 1) = $PID Then
                    $hWnd = $winlist2[$i][1]
                    ExitLoop
                EndIf
            EndIf
        Next
        Sleep(100)
    Until $hWnd <> 0
    Return $hWnd
EndFunc ;==>_GetHwndFromPID

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

  • Similar Content

    • BlazerV60
      By BlazerV60
      Hello all,
      I've written the code below which launches chrome in incognito mode and then proceeds to go to the autoit website.
      From my understanding, the Run() command is also supposed to output the PID number related to the application that got launched from the Run command.
      However when I run the below lines, it outputs a PID number that is different from the newly launched chrome browser's PID number, does anyone know why and possibly explain how I could retrieve the accurate PID number associated with the newly launched browser?
      Global $iPid = Run(@ComSpec & ' /c start chrome.exe https://www.autoitscript.com/forum/ -incognito' ,"", "") msgbox(0,"",$iPid) Thank you,
      Brian
    • Progh0st
      By Progh0st
      Is it posible to get Internet traffic from a PID, like download and upload speeds. I did some research but nothing useful. ty
    • meows
      By meows
      Func Button2Click() ;==> SonoLvl2 ******************************************************* SoundPlay(@ScriptDir & "\schoolbell.wav", 1) Local $Test2 = IniRead(@ScriptDir & "\runer.ini", "Levels", "LComplete1", "Default Value") If $Test2 = 1 Then ; $updatepid = RunWait(@ScriptDir & "\SonoLvl2\SonoLvl2_.exe", "", @SW_SHOWDEFAULT) Else MsgBox(4096, "", "You did not complete Lesson1") EndIf ;MsgBox($MB_SYSTEMMODAL, "Bug Report Environment", _DebugBugReportEnv()) IniWrite(@ScriptDir & "\runer.ini", "Levels", "LComplete2", "2") EndFunc ;==>Button2Click I have tried PID checks and updatepid per the help file and they just didn't work out. and usually caused errors. Then (not included I tried making a separate function to write to a INI file. that was a lesson in frustration and defeat. It worked.. just the same as the code in the function now. as soon as you click the button and the runwait line starts the ini gets updated. The file can only be written to after runwait is running is closed. Also tried the ProcessWait, ProcessWaitClose,  ShellExecute, ShellExecuteWait
      Then in desperation I tried a Debug i read about
      Func Button2Click() ;==> SonoLvl2 ******************************************************* $__iLineNumber=162 & ' - SoundPlay(@ScriptDir & "\schoolbell.wav", 1)•' SoundPlay(@ScriptDir & "\schoolbell.wav", 1) $__iLineNumber=163 & ' - Local $Test2 = IniRead(@ScriptDir & "\runer.ini", "Levels", ...•' Local $Test2 = IniRead(@ScriptDir & "\runer.ini", "Levels", "LComplete1", "Default Value") $__iLineNumber=164 & ' - If $Test2 = 1 Then•' If $Test2 = 1 Then $__iLineNumber=165 & ' - $updatepid = RunWait(@ScriptDir & "\SonoLvl2\SonoLvl2_.exe", ...•' $updatepid = RunWait(@ScriptDir & "\SonoLvl2\SonoLvl2_.exe", "", @SW_SHOWDEFAULT) Else $__iLineNumber=167 & ' - MsgBox(4096, "", "You did not complete Lesson1")•' MsgBox(4096, "", "You did not complete Lesson1") EndIf ;MsgBox($MB_SYSTEMMODAL, "Bug Report Environment", _DebugBugReportEnv()) $__iLineNumber=173 & ' - IniWrite(@ScriptDir & "\runer.ini", "Levels", "LComplete2", ...•' IniWrite(@ScriptDir & "\runer.ini", "Levels", "LComplete2", "2") EndFunc ;==>Button2Click unfortunately I was not smart enough to get it to work for me. What I wanted was a Debugger that explains what each line does and why. Then I figured out that isn't happening.
    • Graywalker
      By Graywalker
      Task : If Java.exe opens and it's parent process is a browser, get the URL of the web page it has open (hopefully the URL that started java).

      I would love a way to do it remotely, but can live with having to run a monitor on the local machine.

      What I have now is a function that uses WMI to query win32_process and get the processes and parent process id, searches that for Java and puts that info into a report.

      I want to include the URL of the webpage that launched java. What I have so far is below, but it doesn't let me tie the Process ID to the window I get the URL from. It also will not get Firefox windows. The Shell method only gets Shell windows. I have nine windows open, but it only picks up two - internet explorer and file system explorer - missing both Firefox windows and all their tabs.

      So, the question is - how to get a browser object when I start with only a Process ID and get the URL from that object? On a remote computer?


      $oShell = ObjCreate("shell.application") ; Get the windows shell object $oShellWindows = $oshell.windows ; Get open windows If IsObj($oShellWindows) Then $string = "" For $Window in $oShellWindows ; count all windows $Wpid = ObjName($Window,3) $string = $string & $Window.LocationName & " ; " & $Window.FullName & " ; " & $Wpid & @CRLF If StringInStr($Window.FullName, "iexplore") Then MsgBox(0,"Internet Explorer", "You browsing the URL " & $Window.Document.Location.href) EndIf Next MsgBox(0,"Shell Windows", "You have the following " & $oShellWindows.Count & " windows open:" & @CRLF & $string); EndIf
      Fantasy code I would like to work:

      $objWMIService = ObjGet("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" _ & $strPCName & "\root\cimv2") If IsObj($objWMIService) Then $colProcesses = $objWMIService.ExecQuery( _ "select * from win32_process") For $objProcess In $colProcesses If $objProcess.ProcessId = $javaparentPID Then $Name = $objProcess.LocationName $URL = $objProcess.Document.Location.href Endif
      Code that gets the process IDs :

      Func _ProcessInfo($strPCName) Dim $i = 0 Dim $User, $Domain, $objWMIService, $colProcesses, $procnum Dim $Aprocesses[1][9] Dim $pi, $ppi, $parent, $parentfound $objWMIService = ObjGet("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" _ & $strPCName & "\root\cimv2") ; Gather process information into an array If IsObj($objWMIService) Then $colProcesses = $objWMIService.ExecQuery( _ "select * from win32_process") For $objProcess In $colProcesses $i = $i + 1 ReDim $Aprocesses[$i + 1][9] $Aprocesses[$i][1] = $objProcess.ProcessId $Aprocesses[$i][2] = $objProcess.Caption $Aprocesses[$i][3] = $objProcess.HandleCount $Aprocesses[$i][4] = $objProcess.ExecutablePath $Aprocesses[$i][5] = $objProcess.ParentProcessId $Aprocesses[$i][6] = $objProcess.CreationDate If $objProcess.GetOwner($User, $Domain) = 0 Then $Aprocesses[$i][7] = $Domain & _ "\" & $User Else $Aprocesses[$i][7] = "" EndIf Next $Aprocesses[0][0] = $i $procnum = $i ;_ArrayDisplay($Aprocesses) ; Process the information about the Processes - LOL! $parentfound = 0 For $pi = 1 To $procnum ; only looking for Java, so : If StringInStr($Aprocesses[$pi][2], "java") Then $parent = $Aprocesses[$pi][5] For $ppi = 1 To $procnum If $Aprocesses[$ppi][1] = $parent Then $parentfound = 1 ExitLoop EndIf Next If $parentfound = 1 Then ; It has a parent process still running! $line = $strPCName & "," & $Aprocesses[$pi][1] & "," & $Aprocesses[$pi][2] & "," & $Aprocesses[$pi][3] & "," & _ $Aprocesses[$pi][4] & "," & $Aprocesses[$pi][5] & "," & $Aprocesses[$pi][6] & "," & _ $Aprocesses[$ppi][6] & "," & $Aprocesses[$ppi][2] & "," & $Aprocesses[$ppi][4] & "," & _ $Aprocesses[$ppi][7] FileWriteLine($LogFile, $line) Else ; parent process left. No, little java, its not your fault... :) $line = $strPCName & "," & $Aprocesses[$pi][1] & "," & $Aprocesses[$pi][2] & "," & $Aprocesses[$pi][3] & "," & $Aprocesses[$pi][4] & "," & _ $Aprocesses[$pi][5] & "," & $Aprocesses[$pi][6] & ",Parent already closed or not found" & ",Owner = ," & $Aprocesses[$pi][7] FileWriteLine($LogFile, $line) EndIf EndIf $parentfound = 0 $ppi = 0 Next Else FileWriteLine($LogFile, $strPCName & ",Unable to query WMI on endpoint") EndIf EndFunc ;==>_ProcessInfo