在Windows11上使用win32gui模块的Python3.10.5中,我想创建一个简单的窗口切换应用程序.首先,我列出了所有正在运行的窗口的hwnd,然后在代码中的其他地方,我使用给定的hwnd切换到其中一个窗口.代码的相关和简化部分如下所示:
def winEnumHandler(hwnd, ctx):
if win32gui.IsWindowVisible(hwnd):
windows.append(hwnd)
def switchToWindow(hwnd):
win32gui.SetForegroundWindow(hwnd)
def main():
windows = []
win32gui.EnumWindows(winEnumHandler, None)
main()
如果我的使用wxPython模块构建的Python应用程序在前台,并且我想要切换到除我的Python应用程序之外的窗口,但每当在前台有另一个应用程序,我想要切换回我的应用程序的主框架或从其运行该Python应用程序的Windows命令行时,代码都可以正常工作,我会收到以下错误:
Exception in thread Thread-2 (showSwitcher):
Traceback (most recent call last):
File "C:\Users\asamec\AppData\Local\Programs\Python\Python310-32\lib\threading.py", line 1016, in _bootstrap_inner
self.run()
File "C:\Users\asamec\AppData\Local\Programs\Python\Python310-32\lib\threading.py", line 953, in run
self._target(*self._args, **self._kwargs)
File "c:\Users\asamec\Dropbox\DIY\Python\WinSwitcher\WinSwitcher\src\WinSwitcher.py", line 207, in showSwitcher
self.switchToApp(app)
File "c:\Users\asamec\Dropbox\DIY\Python\WinSwitcher\WinSwitcher\src\WinSwitcher.py", line 165, in switchToApp
self.switchToWindow(hwnd)
File "c:\Users\asamec\Dropbox\DIY\Python\WinSwitcher\WinSwitcher\src\WinSwitcher.py", line 172, in switchToWindow
win32gui.SetForegroundWindow(hwnd)
pywintypes.error: (5, 'SetForegroundWindow', 'Access is denied.') t
所以问题是:我如何绕过"访问被拒绝"异常,为什么在只从另一个窗口切换到在后台运行的我的Python应用程序窗口的情况下抛出它,而不是在从前台的应用程序窗口切换到其他窗口的情况下抛出?
更新
根据为这篇文章提供的第一个版本,似乎由于Windows系统的限制,使用win32gui模块及其API无法进行所需的窗口切换.那么问题是:有没有其他方法可以切换到特定的窗口,即使在Python应用程序不在前台运行的情况下?我之所以问这个问题,是因为如果进程ID已知,则实际上可以使用pywinauto Python模块进行这种切换,代码如下:
from pywinauto import Application
app = Application().connect(process=pid)
app.top_window().set_focus()
我不想使用上述代码的最初原因是我认为它执行得很慢,然而,我发现性能问题出在代码的其他部分.因此,我将这个问题的第一个答案标记为可接受的问题,因为它也回答了我的后续问题:为什么pywinAuto方法不受Windows系统限制的影响?
被接受的ANSER提供了一种解决方案,该解决方案不需要所需应用的PID和用于切换到该应用的相关PYWINAUTO方法.相反,它提供了一种切换到所需窗口的解决方案,而不是通过窗口的hwnd应用程序,这实际上是问题的初衷.答案还解释说,绕过Windows系统窗口切换限制的解决方法在于使用在运行win32gui.SetForegroundWindow(hwnd)
方法之前将鼠标指针移出屏幕的trap .