Windows 11下PrintWindow/WM_PRINT随机性能缓慢问题排查求助
Windows 11下PrintWindow捕获特定Java应用窗口性能异常问题
我在Windows 11系统上使用windll.user32.PrintWindow(该函数会调用WM_PRINT)捕获被遮挡窗口的截图。功能正常,但从Windows 10升级到Windows 11后,性能变得极不稳定:Win10下捕获耗时通常低于30ms,Win11下有时接近该值,但偶尔会反复出现耗时接近300ms的情况,且持续数小时(截图以循环方式运行),这种情况在Win10运行数月期间从未发生。导致性能缓慢的核心代码行是PrintWindow调用。
有趣的是,性能缓慢仅出现在捕获某特定第三方应用时,该应用基于Java开发,我无法获取其源代码。使用相同代码捕获其他应用时,性能符合预期(约20-30ms)。
补充信息
- 捕获整个窗口或仅客户区(
WM_PRINT或WM_PRINTCLIENT)的耗时大致相同。 - 耗时与捕获窗口大小呈线性正相关,而其他应用无此特性——无论窗口是全屏还是极小化,PrintWindow耗时均约30ms。
- 性能缓慢在低配机器(i5 9600、12GB内存)和高配机器(i7 10700、32GB内存)上均会出现,其中低配机器曾在Win10下稳定实现低于30ms的捕获耗时。
- 性能下降时,CPU和GPU负载未过高(任务管理器显示占用率低于3%),且未发现触发性能下降的规律。
- 已关闭系统动画设置,且窗口未进行最小化/还原操作,因此动画因素可排除。
- 增加目标应用中的控件会使截图耗时略有增加,但即使将控件减至最少,仍无法达到理想的30ms耗时。
初步猜测
- 系统对CPU/GPU要求过高:但在i7 10700和i5机器上测试结果一致,可排除该猜测。
- 目标应用消息队列负载过高,导致PrintWindow调用排队:但耗时与窗口大小线性相关的特性与此猜测不符,且调用RedrawWindow后无改善。
临时解决方案/Workaround
- 在不丢失必要信息的前提下,尽量缩小目标窗口尺寸。
- 并发捕获多个区域后拼接成完整截图。
- 使用BitBlt捕获桌面屏幕(需保证目标窗口可见)。
以上方案均未解决核心问题——为何该特定窗口的绘制速度远慢于其他窗口,恳请各位提供思路。
代码实现
以下为Python代码,核心的PrintWindow调用直接调用Windows DLL,欢迎提供任意编程语言的思路/workaround。
def capture_screen_from_DC(hwnd): l, t, r, b = win32gui.GetWindowRect(hwnd) w = r - l h = b - t hwndDC = win32gui.GetWindowDC(hwnd) mfcDC = win32ui.CreateDCFromHandle(hwndDC) destDC = mfcDC.CreateCompatibleDC() saveBitMap = win32ui.CreateBitmap() saveBitMap.CreateCompatibleBitmap(mfcDC, w, h) destDC.SelectObject(saveBitMap) windll.user32.PrintWindow(hwnd, destDC.GetSafeHdc(), 2) bmpinfo = saveBitMap.GetInfo() bmpstr = saveBitMap.GetBitmapBits(True) im = Image.frombuffer('RGB', (bmpinfo['bmWidth'], bmpinfo['bmHeight']), bmpstr, 'raw', 'BGRX', 0, 1) win32gui.DeleteObject(saveBitMap.GetHandle()) destDC.DeleteDC() mfcDC.DeleteDC() win32gui.ReleaseDC(hwnd, hwndDC) return im
内容的提问来源于stack exchange,提问作者Wojciech
相关产品推荐
相关产品推荐

