Pywinauto:无法将窗口带到前台

时间:2016-09-30 15:10:33

标签: python pywinauto

使用基于Python的自动化工具。

想象一下,有一个应用程序池正在运行:

APPS_POOL = ['Chrome', 'SomeApp', 'Foo']

脚本在循环中运行(每秒一次),需要在它们之间随机切换:

# Init App object
app = application.Application()

# Select random app from the pull of apps
random_app = random.choice(APPS_POOL)
app.connect(title_re=".*%s" % random_app)
print 'Select "%s"' % random_app

# Access app's window object
app_dialog = app.window_(title_re=".*%s.*" % random_app)

if app_dialog.Exists():
    app_dialog.SetFocus()

第一次它工作正常,但是每一个 - 窗口都不会被带到前台。有什么想法吗?

编辑:脚本从Win7 CMD运行。是否可能系统"阻止"一旦焦点设置到其他窗口,CMD就会以某种方式设置焦点?

4 个答案:

答案 0 :(得分:8)

我认为SetFocus有点儿错误。至少在我的机器上我收到错误:error: (87, 'AttachThreadInput', 'The parameter is incorrect.')。所以也许你可以玩最小化/恢复。请注意,这种方法也不是防弹措施。

import random
import time
from pywinauto import application
from pywinauto.findwindows import WindowAmbiguousError, WindowNotFoundError

APPS_POOL = ['Chrome', 'GVIM', 'Notepad', 'Calculator', 'SourceTree', 'Outlook']


# Select random app from the pull of apps
def show_rand_app():
    # Init App object
    app = application.Application()

    random_app = random.choice(APPS_POOL)
    try:
        print 'Select "%s"' % random_app
        app.connect(title_re=".*%s.*" % random_app)

        # Access app's window object
        app_dialog = app.top_window_()

        app_dialog.Minimize()
        app_dialog.Restore()
        #app_dialog.SetFocus()
    except(WindowNotFoundError):
        print '"%s" not found' % random_app
        pass
    except(WindowAmbiguousError):
        print 'There are too many "%s" windows found' % random_app
        pass

for i in range(15):
    show_rand_app()
    time.sleep(0.3)

答案 1 :(得分:2)

在某些情况下,接受的答案没有正常工作 - 某些基于Qt4-5的应用程序由于某种原因没有正确加载GUI。所以,我找到了SetFocus()bug的另一种解决方法。

from pywinauto import Application, win32defines
from pywinauto.win32functions import SetForegroundWindow, ShowWindow

app = Application().connect(path="C:\path\to\process.exe")
w = app.top_window()

#bring window into foreground
if w.HasStyle(win32defines.WS_MINIMIZE): # if minimized
    ShowWindow(w.wrapper_object(), 9) # restore window state
else:
    SetForegroundWindow(w.wrapper_object()) #bring to front

答案 2 :(得分:1)

以上是一个完美的答案,但是不建议使用HasStyle的新方法如下

if m.has_style(win32defines.WS_MINIMIZE): # if minimized
    ShowWindow(m.wrapper_object(), 9) # restore window state
else:
    SetForegroundWindow(m.wrapper_object()) #bring to front

...... 另一种交易方式。

app = Application(backend='win32').connect(path="")
app.top_window().set_focus()

答案 3 :(得分:1)

包含在本期中

Microsoft.Exchange.WebServices

SetForegroundWindow 函数在某些 pywinauto 版本 < 0.6.7 模块中已被弃用。他们建议在该博客中使用 .set_focus()

app = Application(backend='uia').start(app_path)
app.top_window().set_focus()

或者建议使用 win32 模块 SetForegroundWindow 函数,即使 pywinauto 在后台使用相同的函数。

import win32gui 
app = Application(backend='uia').start(app_path)
shell = win32com.client.Dispatch("WScript.Shell")
shell.SendKeys('%')
win32gui.SetForegroundWindow(app.top_window().handle)

在上面提到的代码中,我们不能像那样使用 win32gui.SetForegroundWindow 在调用该函数之前我们需要发送 alt 键函数,以便 win32gui.SetForegroundWindow 函数正常工作并设置应用程序窗口到前台。

参考:https://github.com/pywinauto/pywinauto/issues/785