AutoIt等到浏览器窗口可见后不按预期工作

时间:2016-03-09 16:58:58

标签: windows autoit windows-scripting

考虑到我的AutoIt脚本中有一个Web浏览器窗口('firefox')的句柄($browser_handle)。

在我知道firefox浏览器窗口在我的显示器上打开并可见之后,我想执行一些击键,以便我可以使用它进行聚焦 -

WinActivate($browser_handle)

WinWaitActive($browser_handle)

为了确保在我尝试将窗口聚焦之前窗口是可见的,我有一个while循环,等待窗口句柄的状态可见(2)。

While (Not BitAND(WinGetState($browser_handle), 2)) WEnd //until window visible

如果我在while循环之前使用Sleep(5000)函数,那么我不会遇到任何问题。

如果我在脚本中不使用任意Sleep函数,则While循环条件永远不会变为true并变为无限循环。

当我尝试检查没有WinGetState($browser_handle)函数时Sleep的返回值是什么时,

即使浏览器可见,它仍然 5 ,并且在浏览器窗口关闭后变为 0

我无法理解为什么WinGetState返回值永远不会变为 2 (可见),即使浏览器在没有Sleep功能时可见。

这是一个可以重现问题的测试代码 -

#include <Constants.au3>
Local $browser_name = 'C:\Program Files (x86)\Internet   Explorer\iexplore.exe'
Run($browser_name)

ProcessWait('iexplore.exe')

Local $browsers = ProcessList('iexplore.exe')

Local $pid = $browsers[1][1];

_WinActiveByPID($pid)

Local $sText = WinGetTitle("[ACTIVE]")

; Display the window title.
MsgBox($MB_SYSTEMMODAL, "", $sText)

Func _WinActiveByPID($pid)   ;False to WinActivate, True to just see if it's active
Local $aWL = WinList()
For $iCC = 1 To $aWL[0][0]
        If ($aWL[$iCC][0] <> '') And _
            (WinGetProcess($aWL[$iCC][1]) = $pid) Then
                 While (Not BitAND(WinGetState($aWL[$iCC][1]), 2))
                    MsgBox($MB_SYSTEMMODAL, "", WinGetState($aWL[$iCC][1]))
                 WEnd
                 WinWait($aWL[$iCC][1])
                 WinActivate($aWL[$iCC][1])
                 WinWaitActive($aWL[$iCC][1])
                 Return 1
        EndIf
 Next
Return SetError(2, 0, 0)
EndFunc

注意:

  1. WinWait在这种情况下不起作用,如果您看到链接中的示例在Sleep后面有WinWait,则即使窗口被隐藏,此函数也会返回

  2. 原始脚本中的浏览器窗口不是使用Run启动的,它是一个打开浏览器的Java程序。我知道Run方法返回浏览器的PID,我可以用它来解决这个问题,但由于它是从Java开始的,我必须使用ProcessList来获取浏览器的PID。

  3. 请让我知道如何让这个工作。

    由于

2 个答案:

答案 0 :(得分:0)

你有无缘无故的事情。让我告诉你。

Local $browser_name = 'C:\Program Files (x86)\Internet Explorer\iexplore.exe'
Run($browser_name)

ProcessWait('iexplore.exe')
Sleep(500)      ; because ProcessWait will exit when the process is created not when the window is visible. If your computer is slow you will have an problem

Local $BrowsersHWND = WinList()
Local $hBrowserHandle[2]

For $i = 0 To $BrowsersHWND[0][0] -1
    If StringInStr($BrowsersHWND[$i][0], "Internet Explorer") Then
        $hBrowserHandle[0] = $BrowsersHWND[$i][0]   ;title
        $hBrowserHandle[1] = $BrowsersHWND[$i][1]   ;handle
        ExitLoop
    EndIf
Next

If $hBrowserHandle[0] = "" Or $hBrowserHandle[1] = "" Then Exit MsgBox(0, 0, "Internet Explorer not found")

Local $hState = WinGetState($hBrowserHandle[0])
Local $sVisibleStates[24] = [2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 34, 35, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47]  ;visible states
Local $hCheck = False
For $j = 0 To UBound($sVisibleStates) -1
    If $hState = $sVisibleStates[$j] Then
        ConsoleWrite("Window state(visisble): " & $hState & @LF)
        $hCheck = True
        ExitLoop
    EndIf
Next

If $hCheck = False Then
    ConsoleWrite("Activating: " & $hBrowserHandle[0] & @LF)
    WinActivate($hBrowserHandle[0])
EndIf

我添加了窗口可见的所有状态。 WinWait不会激活任何窗口,我建议您永远不要使用它。它可以无缘无故地冻结脚本。我不会解释为什么,因为它需要页面,但避免它。另请避免使用WinWaitActive。出于类似的原因。 您的代码中存在太多问题,这就是我完全更改它的原因。不值得解释。

答案 1 :(得分:0)

我认为问题不一定是代码,而是可能与逻辑有关。我可能会离开这里,但也许我们不应该寻找2的状态,而是接近15的状态。

带记事本的样本:

$WIN_STATE_EXISTS (1) = Window exists
$WIN_STATE_VISIBLE (2) = Window is visible
$WIN_STATE_ENABLED (4) = Window is enabled
$WIN_STATE_ACTIVE (8) = Window is active

活动窗口(8),启用窗口(4),可见窗口(2)和存在窗口(1)的窗口状态为15。

; Look for notepad and display WindowState number
if WinExists("[Class:Notepad]") Then
   MsgBox($MB_SYSTEMMODAL, "", "Found")

   WinActivate("[Class:Notepad]")
   $WinState = WinGetState("[Class:Notepad]")
   MsgBox($MB_SYSTEMMODAL, "", $WinState)
EndIf