通过 VcXsrv 在 WSL2 上使用图形化界面
启动 VcXsrv
-
在 Windows 上下载 VcXsrv 并安装。
-
运行
-
第一步的设置窗口状态怎么选关系不大,我一般是用 One large window ,默认的 Multiple windows 在多屏情况下显示会有一些问题。然后 Display number 可以用默认的 -1 ,或者设置成 0 (当然也可以是其他的数字,具体内容后面解释)。
-
下一步,选择 Start no client 。
-
下一步,选项全部勾上,Additional parameters 不用管。
-
点下一步,点完成,这时候会出现一个黑色的窗口,这样 VcXsrv 就启动好了。
WSL 启动桌面程序
-
首先下载 xfce4 ,sudo apt install xfce4 。
-
然后在 .bashrc 文件末尾中添加一句 export DISPLAY=xx.xx.xx.xx:0 ,其中的 xx.xx.xx.xx 是 VcXsrv 所在主机的 IP 地址,即在 Windows 的 cmd 或 powershell 中执行 ipconfig 里的以太网适配器的 IPv4 地址。
比如我的是 192.168.31.168 ,所以我要在 .bashrc 中添加 export DISPLAY=192.168.31.168:0 。
-
然后 source .bashrc 或者重新进入 wsl 终端。
-
然后执行 startxfce4 ,如果正常的话,之前 VcXsrv 的黑色窗口就会显示 xfce4 的桌面了,并且 wsl 终端会输出 xfce4 的日志。
发生了什么
整个过程中比较重要的概念是 Display number 和环境变量 $DISPLAY 。在 VcXsrv 中设置的 Display number 就是 $DISPLAY 中的分号后面的那个数字。当然,如果 VcXsrv 使用默认的 Display number (-1)就是让 VcXsrv 自动设置这个数字,在当前情况下用默认设置也是可以的。
当启动好 VcXsrv 后就相当于在 Windows 上启动了一个虚拟显示器,然后 WSL 的桌面程序需要连接上这个虚拟显示器才能正常显示。Linux 就是通过 $DISPLAY 这个环境变量来寻找目标显示器。网络上有很多 wsl 连接 VcXsrv 的教程的方法是将 $DISPLAY 设置成 :0.0 ,这貌似在 WSL1 上是可行的,但是在 WSL2 上就行不通了。(但是如果用 xrdp 来使用图形界面使用这个设置就是可以的,因为 xrdp 是运行在 wsl 的 Linux 上的,而且 :0.0 的意思其实就是 localhost:0.0 。至于为什么是 0.0 ,是因为这两个数字分别代表 Display 和 Screen,即 D.S 。 0.0 的意思是 0 号 Display 的 0 号 Screen 。至于更详细的解释可以在 Linux 中执行 man X 来查看。)
网络上另外还有一个方法是将 $DISPLAY 设置成 $(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0 ,这个值是 /etc/resolv.conf 中的 nameserver 的 IP 。不知道为什么这个方法在我的机子上也行不通(可能是因为别人的 wsl2 的 nameserver 的 IP 和 Windows 的 IP 是一样的?)。
而 $DISPLAY 的本质是为了告诉 Linux 的图形程序 X server 的地址和 Display number。所以将地址设置成 VcXsrv 所在主机的 IP 地址那应该是没问题的。如果执行 startxfce4 还是连接不上,并显示 xrdb: Connection timed out 那么检查下 IP 能否 ping 通,以及可能要设置下 WIndows 的防火墙规则。
其他
为什么设置的最后一步要全点上勾。
最后一个勾是 Disable access control ,这是允许所有客户程序都能连接这个 VcXsrv。有的教程说要在最后一步的 Additional parameters fo VcXsrv 中加上 -ac 这个参数,但其实这个参数应该和勾上 Disable access control 的作用是一样的。因为 -ac 的解释就是 disable access control restrictions 。
如果不把 export 写在 .bashrc 中会怎么样
如果只在终端里设置 $DISPLAY 的值其实也能运行,但是这样在图形界面中运行一些图形程序的时候可能就会出问题了。因为只在终端执行 export ... 那么环境变量只会在这个终端有用,如果退出终端或者打开新的终端 $DISPLAY 的值就没了,所以要放在 .bashrc 中。当然用其他永久设置环境的方法也是可以的。