Pywinauto在Windows 11触发MemoryError但Windows 10正常求助
问题:Windows 11下pywinauto触发MemoryError,Windows 10正常运行
我有一段用pywinauto给指定窗口发送文本和回车键的代码,在Windows 10上运行正常,但在另一台Windows 11机器上触发MemoryError。两台设备都配备32GB内存,搜索相关问题后未找到解决方案。
代码示例
import pywinauto import time boolBisCheckbox = False def parar(eachFfox): global boolBisCheckbox if boolBisCheckbox == False: appname = r"\[FIREFOX " + eachFfox + r"\]" else: appname = r"\[FIREFOX " + eachFfox + r"2\]" handle = pywinauto.findwindows.find_window(title_re=appname) app = pywinauto.application.Application(backend="win32").connect(handle=handle) Wizard = app[appname] Wizard.send_keystrokes("parar") time.sleep(0.5) Wizard.send_keystrokes("{ENTER}") time.sleep(6) Wizard.send_keystrokes("{ENTER}") time.sleep(10) Wizard.send_keystrokes("{ENTER}") input() parar("A")
报错信息
Traceback (most recent call last): File "C:\pypy\testParar.py", line 23, in <module> parar("A") File "C:\pypy\testParar.py", line 12, in parar handle = pywinauto.findwindows.find_window(title_re=appname) File "C:\Python\lib\site-packages\pywinauto\findwindows.py", line 113, in find_window element = find_element(**kwargs) File "C:\Python\lib\site-packages\pywinauto\findwindows.py", line 84, in find_element elements = find_elements(**kwargs) File "C:\Python\lib\site-packages\pywinauto\findwindows.py", line 283, in find_elements elements = [elem for elem in elements if _title_match(elem)] File "C:\Python\lib\site-packages\pywinauto\findwindows.py", line 283, in <listcomp> elements = [elem for elem in elements if _title_match(elem)] File "C:\Python\lib\site-packages\pywinauto\findwindows.py", line 279, in _title_match t = w.rich_text File "C:\Python\lib\site-packages\pywinauto\win32_element_info.py", line 83, in rich_text return handleprops.text(self.handle) File "C:\Python\lib\site-packages\pywinauto\handleprops.py", line 92, in text buffer_ = create_unicode_buffer(length) File "C:\Python\lib\ctypes\_init_.py", line 297, in create_unicode_buffer buf = buftype() MemoryError
解决方案
从报错栈可以看出,问题出在pywinauto获取窗口文本时,尝试创建的缓冲区长度异常导致内存错误,这是Windows 11下部分窗口(尤其是Firefox)的文本获取逻辑兼容性问题。以下是几种可行的解决方法:
方法1:切换到UIA后端
Windows 11对UIA后端的支持更完善,替换win32后端可以避开文本获取的bug:
# 修改connect部分的后端参数 app = pywinauto.application.Application(backend="uia").connect(handle=handle) # 如果原窗口定位方式失效,改用window方法 Wizard = app.window(title_re=appname)
方法2:绕开pywinauto,用ctypes直接调用Windows API发送输入
如果只需要发送按键和文本,不需要获取窗口内容,可以直接通过窗口句柄调用系统API,跳过pywinauto的文本匹配逻辑:
import ctypes from ctypes import wintypes import time user32 = ctypes.WinDLL('user32', use_last_error=True) # 定义Windows API所需的数据结构 INPUT_KEYBOARD = 1 class KEYBDINPUT(ctypes.Structure): _fields_ = [ ("wVk", wintypes.WORD), ("wScan", wintypes.WORD), ("dwFlags", wintypes.DWORD), ("time", wintypes.DWORD), ("dwExtraInfo", wintypes.LPVOID) ] class INPUT(ctypes.Structure): _fields_ = [ ("type", wintypes.DWORD), ("ki", KEYBDINPUT) ] def send_key(handle, key_code): # 激活目标窗口 user32.SetForegroundWindow(handle) time.sleep(0.1) # 按下按键 input_down = INPUT(type=INPUT_KEYBOARD, ki=KEYBDINPUT(wVk=key_code, wScan=0, dwFlags=0, time=0, dwExtraInfo=None)) user32.SendInput(1, ctypes.byref(input_down), ctypes.sizeof(INPUT)) # 释放按键 input_up = INPUT(type=INPUT_KEYBOARD, ki=KEYBDINPUT(wVk=key_code, wScan=0, dwFlags=2, time=0, dwExtraInfo=None)) user32.SendInput(1, ctypes.byref(input_up), ctypes.sizeof(INPUT)) def send_text(handle, text): user32.SetForegroundWindow(handle) time.sleep(0.1) for char in text: # 转换字符为虚拟键码(仅支持ASCII字符) key_code = ord(char.upper()) send_key(handle, key_code) time.sleep(0.05) # 修改原函数 boolBisCheckbox = False def parar(eachFfox): global boolBisCheckbox if boolBisCheckbox == False: appname = r"\[FIREFOX " + eachFfox + r"\]" else: appname = r"\[FIREFOX " + eachFfox + r"2\]" handle = pywinauto.findwindows.find_window(title_re=appname) # 直接发送文本和回车 send_text(handle, "parar") time.sleep(0.5) send_key(handle, 0x0D) # Enter键的虚拟键码 time.sleep(6) send_key(handle, 0x0D) time.sleep(10) send_key(handle, 0x0D)
方法3:升级pywinauto到最新版本
pywinauto的新版本可能修复了Windows 11下的兼容性问题,执行升级命令:
pip install --upgrade pywinauto
内容的提问来源于stack exchange,提问作者itegumo
相关产品推荐
相关产品推荐

