通过 WSL 工作时截取 windows 桌面

Screenshotting the windows desktop when working through WSL

我主要使用 Windows,其中 运行 WSL2。因此,从子系统中的 python 脚本 运行ning,我想截取 windows 监视器上的任何内容,就这么简单:

v1

import mss
import os

os.environ['DISPLAY'] = ':0'

with mss.mss() as sct:
    sct.shot()

这只给出了“分段错误”错误,没有图像。因此,我尝试在 Windows 中设置 vcxsrv,并且我能够通过服务器从 Windows 中的子系统中打开内容,但是我无法通过其他方式获得它..

我只想访问 windows 屏幕以便截屏。非常感谢有关如何通过 wsl 访问监视器的任何帮助,我在 google..

上找不到太多

如果您使用的是笔记本电脑,您可以点击 windows 按钮并使用 prtsc 截取屏幕截图;如果您使用的是 PC,您可以使用 OBS 其录制软件,该软件几乎可以执行任何操作。

您尝试解决的问题是 WSL/Linux Python 的 mss,如您所见,无法捕获 Windows桌面。作为 MSS 的 Linux 版本,它只能与像 X 这样的 Linux 进程和协议进行通信。启动 VcXsrv 可能会帮助您实现目标,因为您可能能够捕获X 输出,但您可能需要 运行 来自终端内部的 Python 应用程序,即 X window.

中的 运行

无论如何,您说过您的目标是捕获整个 Windows 桌面,而不仅仅是 VcXsrv 中的 X 输出。为此,您需要使用某种 Windows 过程。

不过别担心;使用 WSL 的互操作,您仍然可以在 WSL/Linux Python 内部执行此操作。我们只需要呼唤某种 Windows .exe

您可以在 Windows 中使用 dozens of third-party apps 来创建屏幕截图。但我更喜欢使用不需要任何额外安装的解决方案。

所以我为此求助于 PowerShell,因为您可以轻松调用 powershell.exe 并从 WSL 传入脚本。有一个 number of examples here on Stack Overflow, but I ended up going slightly "lower tech" to try to simplify a bit. The code here is most similar to this solution,所以如果你想对此进行扩展,请参考它。

来自 WSL/Linux Python:

import os
os.system("""
    powershell.exe \"
        Add-Type -AssemblyName System.Windows.Forms
        [Windows.Forms.Sendkeys]::SendWait('+{Prtsc}')
        $img = [Windows.Forms.Clipboard]::GetImage()
        $img.Save(\\"$env:USERPROFILE\Pictures\Screenshots\screenshot.jpg\\", [Drawing.Imaging.ImageFormat]::Jpeg)\"
""")

这实质上是发送ShiftPrintScreen键和弦将当前桌面捕获到剪贴板,然后保存剪贴板。引用可能会有点麻烦,因为您实际上是将 PowerShell 包装在 Python 脚本中的 /bin/sh 中。

请注意,即使您在 Linux Python 中,因为我们调用的是 Windows PowerShell,它采用 Windows 路径格式(C:\Users\Username\Pictures...) 而不是 Linux 版本 (/mnt/c/Users/...).

虽然我对此没有任何时间问题,但您可能需要插入小的延迟。再次,请参考现有的答案。本方案主要是说明如何通过WSL的Python使用PowerShell来实现。