我一直在努力修复一个曾经可以正常工作的 WSL2 系统,该系统可以在 Windows 上显示 Linux 应用程序的 GUI。以前,我使用的是名为 GWSL 的第三方应用程序/xserver,但有一天,我出于某种不相关的原因卸载了 Windows 上的 Docker Desktop,结果一切都搞砸了。
从那时起,我了解到 WSL 的当前版本带有自己的图形支持(WSLG),由微软自己提供,并且我能够启动安装在 Ubuntu 上的任何应用程序,例如google-chrome
等,只需一个初始步骤。
我仍然对所有这些 x 服务器和 DISPLAY 的东西感到很困惑,我唯一关心的是让 Playwright 启动浏览器来测试一些网页内容,但它一直给我这个错误
Looks like you launched a headed browser without having a XServer running.
Set either 'headless: true' or use 'xvfb-run <your-playwright-app>
所以我并不是在寻求剧作家的帮助,而是想了解到底发生了什么。
当我在 WSL2 上启动 Ubuntu 并运行
ps e | grep -Po " DISPLAY=[\.0-9A-Za-z:]* " | sort -u
我明白了
DISPLAY=10.255.255.254:0.0
DISPLAY=:0
这是否意味着我有两个显示器?我想是的。
当我跑步时echo $DISPLAY
我得到10.255.255.254:0.0
当我跑步时google-chrome
我得到Missing X server or $DISPLAY
当我运行时,export DISPLAY=:0
我不仅可以成功运行google-chrome
Playwrights 版本的chromium
(found me\.cache\ms-playwright\chromium-1134\chrome-linux\chrome
),而且没有任何问题。
然而,当我尝试再次运行 Playwright 测试时,它仍然告诉我没有运行 XServer。
所以此时,我试图了解我处于什么状态。如果我实际上可以通过 Ubuntu 启动 chrome 等并在 Windows 桌面上看到它,那么我真的没有运行 XServer 吗?我的 DISPLAY 是否错误或太多?我们是否认为 Playwright 仅适用于特定的 DISPLAY 或 XServer(端口?ip?)。我在这里有点茫然,不知道还有什么可以调试。我已经安装并运行了大约 1000 个 linux 命令,并尝试了各种 Windows 第三方 xservers。它似乎有点起作用,只是不适用于 Playwright。
X11 显示名称具有以下常规格式:
主机名和屏幕编号部分是可选的:如果主机名为空,则表示本地主机。如果省略屏幕编号,则假定为屏幕 0。
X11显示器是输入设备(通常是键盘和鼠标)和一个或多个物理屏幕的集合,所有这些都由单个用户会话一次控制。一台计算机可以有多个 X11显示器,原因有很多:例如,它可能支持与 Windows 的快速用户切换相当的 X11,或者它可能托管远程 VNC 或 RDP 会话,或者它可能是一个真正的多座席系统:允许两个或更多本地用户登录并同时拥有独立的 GUI 会话。
X11屏幕是一种具有特殊属性的显示设备。当 CRT 是显示技术中最先进的技术时,专业的 CAD 工作站可能拥有一台高刷新率灰度显示器以最大限度地减少眼睛疲劳,以及另一台针对高保真彩色显示进行优化的显示器,用于查看渲染结果。
在现代平板显示器上,全彩是常态,刷新率不会影响眼睛疲劳(至少对于静态图像而言),因此更常见的是将多个物理显示器表示为一个横跨两个显示器的 X11 屏幕。这允许将窗口自由地从一个显示器移动到另一个显示器。因此,在现代系统上,屏幕编号大于 0 是相当意外的。
表示“使用 TCP 连接 IP 地址 10.255.255.254、端口号 6000(= 显示号 + 6000)联系 X11 显示服务器的显示 0、屏幕 0”。屏幕号(最后一位
.0
)是可选的;如果没有指定,则使用屏幕 0。表示“使用最有效的传输机制,连接本地机器的显示器 0,默认屏幕 0”。在 Linux 中,这通常意味着应用程序将首先使用位于 中的 UNIX 套接字连接显示服务器
/tmp/.X11-unix/X0
,并可选择协商共享内存访问 X11 服务器(MIT-SHM X11 协议扩展)和/或直接渲染(直接 GPU 访问;XFree86-DGA 或 DRI 扩展),以便在需要且可用时提高性能。如果 10.255.255.254 是您本地系统的 IP 地址,那么这两个 DISPLAY 规范都会告诉客户端连接到同一个 X11 显示器,但可能使用不同的传输方法。
第一种形式强制在本地使用 TCP;这会导致性能损失,但使得记录会话变得更加容易。
如果与显示号匹配的 UNIX 套接字不可用,并且 X11 服务器正在监听本地 TCP 端口(显示号 + 6000),则第二种形式可能仍然会回退到使用 TCP。
在现代 Linux 中,X11 服务器通常仅默认提供 UNIX 套接字,因为在实际网络连接上使用没有 SSH X11 转发或某些其他加密层的基于 TCP 的连接 X11 连接按照现代标准来说是非常不安全的。
由于基于 Windows 的 X11 服务器主要用于访问远程 X11 显示器,因此它们往往默认启用基于 TCP 的连接,这甚至可能是它们唯一可用的连接方法。
DISPLAY 变量已设置这一事实表明系统中已设置某些内容以假定 X11 服务器可用。但错误消息
表明它现在实际上不可用;要么它没有运行,要么某些东西阻止应用程序联系它。
这
xvfb-run
可能是一个使用虚拟帧缓冲区 X11 服务器运行指定应用程序的脚本:这是一种虚拟 X11 服务器,它实际上并未连接到任何可见显示器,但行为却像已连接到一样。WSLg 进一步使问题复杂化,因为它显然是作为可通过 RDP 访问的 Wayland 显示服务器实现的,并
XWayland
在其上附加了 X11 兼容层。要使 WSLg 正常工作,您显然应该使用 RDP 连接到 WSL2 系统。然后,您可以像
gnome-terminal
第一个一样使用本机 Wayland 应用程序进行测试。如果这样可行,那么核心 Wayland 显示服务器至少正在运行。如果有效,下一步将是验证
/tmp/.X11-unix/X<display number>
UNIX 套接字是否存在以及XWayland
进程是否正在运行,或者是否配置为systemd
在 X11 客户端尝试使用套接字时开始使用套接字激活功能。fuser /tmp/.X11-unix/X0
应该告诉当前与套接字关联的进程的 PID。为了
DISPLAY=10.255.255.254:0.0
使其正常工作,您首先必须验证该 IP 地址中是否有 X11 服务器进程在侦听 TCP 端口 6000。如果该地址属于 WSL2 系统,lsof -i tcp:6000
则应确认 X11 服务器(或兼容层)是否XWayland
确实在侦听该端口。nc -v 10.255.255.254 6000
您可以测试该端口是否确实可连接(软件防火墙?)。XWayland 可能默认不监听 TCP 端口,但 Playwright 可能为其提供 X11 代理。(免责声明:我不知道 Playwright 实际上是怎样工作的。)