Windows 10 如何在WSL2上设置工作X11转发
当从WSL1移动到WSL2时,许多事情会发生变化;显然,这也适用于X11转发。Windows 10 如何在WSL2上设置工作X11转发,windows-10,x11,windows-subsystem-for-linux,x11-forwarding,wsl-2,Windows 10,X11,Windows Subsystem For Linux,X11 Forwarding,Wsl 2,当从WSL1移动到WSL2时,许多事情会发生变化;显然,这也适用于X11转发。 要在Windows 10上使用WSL2的X11转发,就像使用WSL1一样,我需要采取哪些步骤?TL;博士: 将以下内容添加到您的~/.bashrc: export DISPLAY=$(awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null):0 export LIBGL_ALWAYS_INDIRECT=0 export DISPLAY
要在Windows 10上使用WSL2的X11转发,就像使用WSL1一样,我需要采取哪些步骤?TL;博士: 将以下内容添加到您的
~/.bashrc
:
export DISPLAY=$(awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null):0
export LIBGL_ALWAYS_INDIRECT=0
export DISPLAY=$(awk'/nameserver/{print$2;exit}'/etc/resolv.conf 2>/dev/null):0
导出LIBGL\u始终\u间接=1
在X11 Windows服务器上启用公共访问*
为TCP端口6000向windows防火墙添加单独的入站规则,以便允许WSL访问X服务器,如人员所述
如前所述,正如您在中所读到的,WSL2体系结构使用虚拟化网络组件。这意味着WSL2的IP地址与主机不同。 这解释了为什么WSL1的X11转发设置不能简单地传输到WSL2 在关于WSL的UbuntuWiki页面上,您已经可以在下找到适合WSL2的配置。上述Reddit用户也建议使用类似的配置,他还提供了解决方案的另一部分:在Windows下的X11服务器上启用公共访问 这意味着将以下内容添加到
~/.bashrc
:
export DISPLAY=$(awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null):0
export LIBGL_ALWAYS_INDIRECT=0
export DISPLAY=$(awk'/nameserver/{print$2;exit}'/etc/resolv.conf 2>/dev/null):0
导出LIBGL\u始终\u间接=1
并在X11 Windows服务器上启用公共访问*
在Windows 10上为WSL2启用X11转发的最重要部分仍然缺失:Windows防火墙阻止通过默认情况下为WSL配置的网络接口进行连接。要允许WSL访问X服务器,需要针对TCP端口6000的单独入站规则。创建规则后,如人员所述,IP地址范围可以限制在新创建规则的设置中的WSL子网,在范围下:172.16.0.0/12 *:如果使用,则可以通过禁用额外设置上的访问控制来启用X服务器的公共访问:
或者直接使用
ac
标志调用vcxsrv.exe
:vcxsrv.exe-ac
,正如github问题上所指出的那样。我不知道这是否特定于我的配置,但这些解决方案在我的计算机上不起作用。它们返回地址192.168.0.254,这是我的网关,而不是主机
为了让它工作,我必须在我的Ubuntu/WSL2上使用以下内容:
export DISPLAY="`ip -4 address | grep -A1 eth0 | grep inet | cut -d' ' -f6 | cut -d/ -f1`:0"
对于那些可能使用模拟引擎的人,例如ROS/Gazebo、Unity等,需要另一种配置 将这些添加到
~/.bashrc
:
export DISPLAY=$(awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null):0
export LIBGL_ALWAYS_INDIRECT=0
确保在windows中同时启用X11服务器的公共访问和私有访问还禁用X11服务器支持的任何访问控制
如果使用本机opengl,请取消选中。VcXSrv的最终配置如下:
具有较少困难的替代性好X11服务器是和。有关此配置的一些详细信息,请参阅和。使用
/etc/resolv.conf
名称服务器对我不起作用,因为我在/etc/wsl.conf
中禁用了resolv.conf
生成(我有一个自定义的resolv.conf
)
最终,您需要WSL2主机IP地址,这也是您的默认路由。以下是我的Debian WSL2发行版的~/.bashrc
条目:
export DISPLAY=$(ip route | awk '/^default/{print $3; exit}'):0
对于一些像我这样只允许私人网络的人来说 尽管他们应该都打勾 它应该在Windows Defender防火墙上有停止标志 双击它并允许私人和公共连接 因此,所有4项都应勾选为绿色 那么以上来自@NicolasBrauer的回答对我来说是有效的 例如,在您启动和启动时禁用访问控制
export DISPLAY=$(awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null):0
export LIBGL_ALWAYS_INDIRECT=1
抄袭了我的答案
这个想法是利用通过stdio进行通信的能力
先决条件
- 为了在Windows主机中使用socat,您需要一个运行WSL1的分发版。我相信你可以在powershell中这样做,但我没有时间研究这个。也许有人可以在powershell中编写一个stdio->tcp重定向程序,这样我们就不需要2个WSL发行版了
ubuntu
是安装了socat的WSL1发行版的名称):ubuntu
是安装了socat的WSL1发行版的名称):
如何将任何TCP连接从主机转发到WSL2
这只是在做同样的事情,但方向相反。您可以在WSL1发行版中运行以下内容:
socat TCP-LISTEN:5555,fork EXEC:"/mnt/c/Windows/System32/wsl.exe -d ubuntuwsl2 socat - TCP\:localhost\:5555"
演出
在我的电脑上,它可以处理高达150MB/s的数据,因此它不是最快的,但对于大多数应用程序来说已经足够快了。我通过使用Windows主机的LAN适配器IP,成功地使用了现成的VcXsrv防火墙配置(即无需覆盖/禁用任何防火墙规则)。将以下内容添加到我的
~/.bash\u别名中
export DISPLAY=$(pwsh.exe -c ipconfig | grep -A 3 lan | grep IPv4 | head -1 | awk '{ print $NF }'):0
其中,
lan
是我的特定于连接的DNS后缀(您的可能不同,在这种情况下,您应该在上面的命令行中替换它)。以下解决方法适用于我:
设置NetFirewallProfile-Name$(获取NetConnectionProfile)。NetworkCategory-DisabledInterfaceAlases$(获取NetAdapter |其中对象名称-类似
export DISPLAY=$(powershell.exe -c ipconfig | grep -A4 WSL | tail -1 | awk '{ print $NF }' | tr -d '\r'):0
export DISPLAY=$HOSTNAME:0.0
export LIBGL_ALWAYS_INDIRECT=
1. Start ssh service
1.1. Open WSL
1.2. Type: sudo service ssh start
2. Get Windows (WSL net) IP
2.1. Open Powershell
2.2. Type: (ipconfig | Select-String -Pattern 'WSL' -Context 1, 5).Context.PostContext | Select-String -Pattern 'IPv4'
2.3. Get the received IP
3. Set environment variable
3.1. In WSL2 terminal type: export DISPLAY=172.23.64.1:0.0 with the IP of the windows entity (2.3) instead of the place holder
4. Launch Xming
4.1. Open Xlaunch and go with the defaults In Specify parameter settings: Check No Access Control
5. Good luck!
@ECHO OFF
REM Start WSL once to create WSL network interface
wsl exit
REM Find IP for WSL network interface
SET WSL_IF_IP=
CALL :GetIp "vEthernet (WSL)" WSL_IF_IP
ECHO WSL_IF_IP=%WSL_IF_IP%
setx "WSL_IF_IP" "%WSL_IF_IP%"
setx "WSLENV" "WSL_IF_IP/u"
REM Change E:\VcXsrv to your VcXsrv installation folder
START /D "E:\VcXsrv" /B vcxsrv.exe -multiwindow -clipboard -nowgl -ac -displayfd 720
GOTO :EOF
:GetIp ( aInterface , aIp )
(
SETLOCAL EnableExtensions EnableDelayedExpansion
FOR /f "tokens=3 delims=: " %%i IN ('netsh interface ip show address "%~1" ^| findstr IP') DO (
SET RET=%%i
)
)
(
ENDLOCAL
SET "%~2=%RET%"
EXIT /B
)
export DISPLAY=$WSL_IF_IP:0
unset LIBGL_ALWAYS_INDIRECT
# Get the IP Address of the Windows 10 Host and use it in Environment.
HOST_IP=$(host `hostname` | grep -oP '(\s)\d+(\.\d+){3}' | tail -1 | awk '{ print $NF }' | tr -d '\r')
export LIBGL_ALWAYS_INDIRECT=1
export DISPLAY=$HOST_IP:0.0
export NO_AT_BRIDGE=1
export PULSE_SERVER=tcp:$HOST_IP
C:\Windows\System32\wsl.exe -e htop
C:\Windows\System32\wsl.exe lynx
C:\Windows\System32\wsl.exe LIBGL_ALWAYS_INDIRECT=Yes IP=$(host `hostname` | grep -oP '(\s)\d+(\.\d+){3}' | tail -1 | awk '{ print $NF }' | tr -d '\r') DISPLAY=$IP:0.0 PULSE_SERVER=tcp:$IP {yourprogram}
C:\Windows\System32\wsl.exe IP=$(host `hostname` | grep -oP '(\s)\d+(\.\d+){3}' | tail -1 | awk '{ print $NF }' | tr -d '\r') ; export LIBGL_ALWAYS_INDIRECT=Yes export DISPLAY=$IP:0.0 ; cd /mnt/c/Users/{yourusername}/Desktop ; /usr/bin/perl ~/wget-gui.pl
C:\Windows\System32\wsl.exe LIBGL_ALWAYS_INDIRECT=Yes IP=$(host `hostname` | grep -oP '(\s)\d+(\.\d+){3}' | tail -1 | awk '{ print $NF }' | tr -d '\r') DISPLAY=$IP:0.0 PULSE_SERVER=tcp:$IP dbus-launch --exit-with-session gedit
k=$('/mnt/c/Program Files/VcXsrv/xauth.exe' -f 'C:\Users\xxx\Documents\scratch.xauth' -i -n -q 2>/dev/null <<EOF
generate localhost:0 . trusted timeout 604800
list
quit
EOF
)
if [ -n "$k" ]
then
export DISPLAY=$(sed '/^nameserver/ {s/^nameserver\s\s*\([0-9][0-9.]*\)[^0-9.]*$/\1/;p;};d' /etc/resolv.conf):0
xauth -q add $DISPLAY . ${k##* }
export LIBGL_ALWAYS_INDIRECT=true
fi
unset k
#!/bin/bash
start_index=$1
start=${start_index:-0}
# check current settings
declare -i stop=0
if [ ! -z "$DISPLAY" ]; then
timeout 1s xset -display $DISPLAY q &> /dev/null;
[[ "$?" -eq 0 ]] && echo "Already Set to $DISPLAY" && stop=1;
fi
# scan displays 0-17
for port in $(seq $start 17);
do
[[ 1 -eq $stop ]] && break;
grp="ipconfig.exe | grep IPv4 | tr -d '\015' | sed 's#.*: \(.*\)\$#\1:${port}.0#;'"
for ipd in $(eval $grp)
do
echo Trying $ipd;
timeout 1s xset -display $ipd q &> /dev/null;
# command was sucessful
[[ "$?" -eq 0 ]] && export DISPLAY=$ipd && echo $ipd was set && stop=1;
##echo "Trying next IP...";
done
done