41

如何从 Windows 10 的 Bash Shell 运行图形 Linux 桌面应用程序?

首先,我按照此处所示的步骤安装了 Windows Subsystem for Linux (WSL) ,如下所示:

(1) 安装了 Windows 10 Pro Insider Preview Build 19619。

(2) 安装了 Ubuntu Linux 发行版。

(3) 将分发版本从 WSL 1 更改为 WSL 2。

其次,要从 Windows 10 的 Bash Shell 启用图形 Linux 桌面应用程序,我按照以下步骤操作,如下所示

(4)我安装了一个X Server,就是Xming

(5) 安装基于 GTK 的图形化 vim 编辑器作为测试,使用:

sudo apt-get install vim-gtk

(6)设置我的显示环境变量

export DISPLAY=:0

(7) 启动应用程序

gvim

但是,这并没有午餐应用程序,我收到以下错误:

E233: cannot open display
Press ENTER or type command to continue
E852: The child process failed to start the GUI
Press ENTER or type command to continue

知道为什么会发生此错误吗?

4

9 回答 9

74

WSL2 中的网络子系统与 WSL1 中使用的不同。您必须考虑访问在 Windows 和 Linux 上运行的网络应用程序的差异:

  • 在 WSL1 中,Linux 使用与 Windows 主机相同的 IP 地址,然后,您可以使用localhost或访问应用程序127.0.0.1
  • 在 WSL2 中,Linux 运行在轻量级虚拟机上,并具有不同的 IP 地址。要访问在 Windows 主机上运行的网络应用程序,您必须使用 Windows IP 地址。

检查 Windows 主机的 IP 地址

有很多方法可以确定 Windows 主机中的 IP 地址。您可以在 WSL Linux 中运行以下命令:

  • cat /etc/resolv.confeth0在 Windows中显示接口的 IP 地址
  • ipconfig.exe显示 Windows 主机中的所有 IP 配置
  • route.exe print显示 Windows 主机中的网络路由配置

为 WSL2 设置 DISPLAY 变量

根据 Microsoft 文档,您可以设置 DISPLAY 变量检查文件nameserver/etc/resolv.conf@fqquiner@VPraharsha已经提到了这一点)

export DISPLAY=$(grep nameserver /etc/resolv.conf | awk '{print $2}'):0.0

但是,我在使用此解决方案时遇到了问题,可能是因为我将笔记本电脑与 WiFi 连接和多个虚拟网络一起使用。代替以前的解决方案,我使用route.exe并检查默认网关中使用的接口来确定 Windows IP 地址。

export DISPLAY=$(route.exe print | grep 0.0.0.0 | head -1 | awk '{print $4}'):0.0

设置 DISPLAY 变量.profile

您可以在~/.profile文件中设置 DISPLAY 变量。我使用了以下代码:

# set DISPLAY to use X terminal in WSL
# in WSL2 the localhost and network interfaces are not the same than windows
if grep -q WSL2 /proc/version; then
    # execute route.exe in the windows to determine its IP address
    DISPLAY=$(route.exe print | grep 0.0.0.0 | head -1 | awk '{print $4}'):0.0

else
    # In WSL1 the DISPLAY can be the localhost address
    if grep -q icrosoft /proc/version; then
        DISPLAY=127.0.0.1:0.0
    fi

fi
于 2021-02-27T12:02:07.530 回答
26

遇到了同样的问题,所以我尝试了这些其他建议,但最终奏效的是允许 vcxsrv 通过公共防火墙。我知道你没有使用 vcxsrv 但也许这对你来说也是同样的问题。

安装 VcXsrv 然后像这些图片一样启用公共防火墙。在命令提示符下使用 wf.msc 打开具有高级安全性的 Windows Defender 防火墙。然后允许像这些图片中的连接。

双击然后允许 VcXsrv 的每个公共配置文件

[在 VcXsrv 防火墙属性中允许连接2

然后从本指南为 Windows 10 WSL2 运行 VcXsrv

通过添加 -ac 附加参数运行 VcXsrv 或在命令提示符“C:\Program Files\VcXsrv\vcxsrv.exe”中键入此参数:0 -multiwindow -clipboard -wgl -ac

然后将其输入到您的 WSL2 终端中

export DISPLAY_NUMBER="0.0"
export DISPLAY=$(grep -m 1 nameserver /etc/resolv.conf | awk '{print $2}'):$DISPLAY_NUMBER
export LIBGL_ALWAYS_INDIRECT=1
# OPTIONAL Set the keyboard layout to US
setxkbmap -layout us
setsid emacs
exit
于 2020-10-06T20:19:07.970 回答
9

添加到 fquinner 的答案,

您的DISPLAY环境变量应设置为export DISPLAY=X.X.X.X:0使用 Windows 主机的 IP 地址作为 WSL2,并且 Windows 主机不在同一个网络设备中,其中 XXXX 是 IP 地址

并且您的 IP 地址在resolv.conf中针对名称服务器 ( $ cat /etc/resolv.conf)列出

或者只是export DISPLAY="`grep nameserver /etc/resolv.conf | sed 's/nameserver //'`:0"自动加载正确的 IP 地址。此外,您可以将其添加到.bashrc.zshrc(如果您使用 Zsh)

于 2020-09-20T10:45:04.247 回答
6

这里有一个故障排除部分,用于在 wsl2 上调试 X11:

https://github.com/cascadium/wsl-windows-toolbar-launcher/blob/master/README.md#troubleshooting

端口转发与 WSL1 不同 - 您的 Linux 服务可以通过 Windows 的 localhost 访问,但反过来不再适用。

因此,您需要使用 Windows 主机的内部 IP 并调整防火墙以允许 WSL 网络通过。

于 2020-05-18T06:34:26.620 回答
4

我个人使用与此处其他答案不同的方法,该方法更符合即将推出的(预览版/Beta 版)WSLg 功能的架构(据我所知)。

我非常习惯于使用远程桌面(又名 RDP)连接到我的各种系统,因此xrdp在我的 WSL 实例中用于图形应用程序是有意义的。这也为我提供了一个完整的桌面环境,能够尝试不同的桌面管理器(尽管我还没有探索过这么多)。

Ubuntu 20.04 上的安装步骤非常简单:

sudo apt install xrdp xfce4 # Or whatever desktop manager you want
sudo cp /etc/xrdp/xrdp.ini /etc/xrdp/xrdp.ini.bak
sudo sed -i 's/3389/3390/g' /etc/xrdp/xrdp.ini # So it doesn't interfere with Windows RDP on 3389

/etc/xrdp/startwm.sh中,注释掉最后两行(提到 Xsession)并添加:

#test -x /etc/X11/Xsession && exec /etc/X11/Xsession
#exec /bin/sh /etc/X11/Xsession
exec startxfce4

开始xrdp

sudo service xrdp start

就是这样——您应该能够使用内置的远程桌面连接应用程序连接到您的 WSL 桌面。要连接的计算机将是localhost:3390. 确保选择 Xorg 作为会话类型。

于 2021-08-20T02:34:39.653 回答
3

在此处输入图像描述 以下说明是从我写的一篇文章中复制和粘贴的,但它丢失了原始格式、链接和屏幕截图:

资料来源: 如何在 WSL2 中使用图形用户界面安装 Ubuntu 桌面


下载VcXsrv:访问官网点击“下载”


安装VcXsrv:打开“vcxsrv-64.1.20.8.1.installer.exe”点击“下一步”点击“安装”点击“关闭”


允许访问 VcXsrv:选中“专用网络”单击“允许访问”


打开 PowerShell:按“⊞ Windows” 在搜索栏中输入“PowerShell” 右键单击​​“Windows PowerShell” 单击“以管理员身份运行”


打开 WSL2:从这些说明下方复制命令 将命令粘贴到 PowerShell 按“Enter”

wsl


安装 Ubuntu 桌面:从这些说明下方复制命令 将命令粘贴到 PowerShell 按“Enter”

sudo apt --yes install ubuntu-desktop


设置用户名变量:从这些说明下方复制命令 将命令粘贴到 PowerShell 按“Enter”

username=$(wslvar USERNAME)


创建 Ubuntu 目录:从这些说明下方复制命令 将命令粘贴到 PowerShell 按“Enter”

mkdir --parents /mnt/c/users/$username/.ubuntu/


打开 Ubuntu 目录:从这些说明下方复制命令 将命令粘贴到 PowerShell 按“Enter”

cd /mnt/c/users/$username/.ubuntu


下载适用于 Microsoft 产品的 Linux 软件存储库:从以下说明复制命令 将命令粘贴到 PowerShell 按“Enter”

Ubuntu 20.04: wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb --output-document packages-microsoft-prod.deb Ubuntu 18.04: wget https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb --output-document packages-microsoft-prod.deb


为 Microsoft 产品安装 Linux 软件存储库:从以下说明中复制命令 将命令粘贴到 PowerShell 按“Enter”

sudo dpkg --install packages-microsoft-prod.deb


更新存储库:从这些说明下方复制命令 将命令粘贴到 PowerShell 按“Enter”

sudo apt update


为 HTTPS 安装 APT 传输:从这些说明下方复制命令 将命令粘贴到 PowerShell 按“Enter”

sudo apt install --yes apt-transport-https


更新存储库:从这些说明下方复制命令 将命令粘贴到 PowerShell 按“Enter”

sudo apt update


安装 .Net:从这些说明下方复制命令 将命令粘贴到 PowerShell 按“Enter”

sudo apt install --yes dotnet-sdk-5.0


将 Arkane 系统添加到源列表目录:从以下说明复制命令 将命令粘贴到 PowerShell 按“Enter”

sudo sh -c 'echo "deb [trusted=yes] https://wsl-translinux.arkane-systems.net/apt/ /" > /etc/apt/sources.list.d/wsl-translinux.list'


更新存储库:从这些说明下方复制命令 将命令粘贴到 PowerShell 按“Enter”

sudo apt update


安装精灵:从这些说明下方复制命令 将命令粘贴到 PowerShell 按“Enter”

sudo apt install --yes systemd-genie


创建 Sudoers 文件:从这些说明下方复制命令 将命令粘贴到 PowerShell 按“Enter”

echo "$USER ALL=(ALL) NOPASSWD:/usr/bin/genie" | sudo EDITOR="tee" visudo --file /etc/sudoers.d/$USER


创建桌面脚本:从这些说明下方复制代码 将代码粘贴到 PowerShell 按“Enter”


# CREATE BASH SCRIPT

# Store block of text with here document
create_bash_script=$(cat << end_of_string

# Define necessary environment variables
export DISPLAY="\$(cat /etc/resolv.conf | grep nameserver | awk '{ print \$2 }'):1.0"
export DESKTOP_SESSION="ubuntu"
export GDMSESSION="ubuntu"
export XDG_SESSION_DESKTOP="ubuntu"
export XDG_CURRENT_DESKTOP="ubuntu:GNOME"
export XDG_SESSION_TYPE="x11"
export XDG_BACKEND="x11"
export XDG_SESSION_CLASS="user"
export XDG_DATA_DIRS="/usr/local/share/:/usr/share/:/var/lib/snapd/desktop"
export XDG_CONFIG_DIRS="/etc/xdg"
export XDG_RUNTIME_DIR="\$HOME/xdg"
export XDG_CONFIG_HOME="\$HOME/.config"
export XDG_DATA_HOME="\$HOME/.local/share" 
export XDG_CACHE_HOME="\$HOME/.cache"
export XDG_DESKTOP_DIR="\$HOME/Desktop"
export XDG_DOCUMENTS_DIR="\$HOME/Documents"
export XDG_DOWNLOAD_DIR="\$HOME/Downloads"
export XDG_MUSIC_DIR="\$HOME/Music"
export XDG_PICTURES_DIR="\$HOME/Pictures"
export XDG_PUBLICSHARE_DIR="\$HOME/Public"
export XDG_TEMPLATES_DIR="\$HOME/Templates"
export XDG_VIDEOS_DIR="\$HOME/Videos"

# Start desktop environment
gnome-session

end_of_string
)

# Store username environment variable in lowercase
username=$(wslvar USERNAME | awk '{ print tolower($0) }') &&

# Save block of text in bash file
echo "${create_bash_script}" > "/mnt/c/users/$username/.ubuntu/02_start_desktop.sh"


下载快捷方式图像:从这些说明下方复制命令 将命令粘贴到 PowerShell 按“Enter”

wget https://assets.ubuntu.com/v1/9fbc8a44-circle-of-friends-web.zip


解压缩快捷方式图像:从这些说明下方复制命令 将命令粘贴到 PowerShell 按“Enter”

unzip -o 9fbc8a44-circle-of-friends-web.zip


创建快捷方式图标:从这些说明下方复制命令 将命令粘贴到 PowerShell 按“Enter”

convert -resize 64x64 ./circle-of-friends-web/png/cof_orange_hex.png ubuntu.ico


Exit WSL2: Copy the command from below these instructions 将命令粘贴到 PowerShell 按“Enter”

exit


创建 VcXsrv 脚本:从这些说明下方复制代码 将代码粘贴到 PowerShell 按“Enter”


# RELOAD VCXSRV SCRIPT

# Store username environment variable in lowercase
$username = $env:username.tolower()  

# Store block of text with here-string
$reload_vcxsrv_script = @"

# Stop vcxsrv proccess that contains "1.0" in the program window title
get-process vcxsrv | where { `$_.mainwindowtitle -like "*1.0*" } | stop-process

# Start vcxsrv process in a large program window on display number one
start-process "c:\program files\vcxsrv\vcxsrv.exe" -argument ":1 -ac -nowgl -multimonitors -dpms"

"@

# Save block of text in powershell file
echo "${reload_vcxsrv_script}" > $env:userprofile/.ubuntu/reload_vcxsrv.ps1


创建 Ubuntu 脚本:从这些说明下方复制代码 将代码粘贴到 PowerShell 按“Enter”


# CREATE VISUAL BASIC SCRIPT

# Store username environment variable in lowercase
$username = $env:username.tolower()           

# Store block of text with here-string
$create_vbs_script = @"

' Run PowerShell script in background
set application = createobject("shell.application")
application.shellexecute "powershell", "-file c:\users\admin\.ubuntu\01_reload_vcxsrv.ps1", "", "", 0

' Allow PowerShell script to complete
wscript.sleep 3000

' Run Bash script in background
set shell= createobject("wscript.shell")
shell.run "wsl sudo genie -c bash /mnt/c/users/admin/.ubuntu/02_start_desktop.sh", 0

"@

# Save block of text in bash file
echo "${create_vbs_script}" > $env:userprofile/.ubuntu/03_start_ubuntu.vbs


创建快捷方式脚本:从这些说明下方复制代码 将代码粘贴到 PowerShell 按“Enter”


# Store block of text with here-string
$create_shortcut_script = @"

# Define location variables
`$shortcut_location = "`$env:userprofile\.ubuntu\Ubuntu.lnk"
`$program_location = "`$env:userprofile\.ubuntu\03_start_ubuntu.vbs"

# Create shortcut
`$object = new-object -comobject wscript.shell
`$shortcut = `$object.createshortcut(`$shortcut_location)
`$shortcut.targetpath = `$program_location
`$shortcut.iconlocation = "`$env:userprofile\.ubuntu\ubuntu.ico"
`$shortcut.save()

"@

# Save block of text in powershell file
echo $create_shortcut_script > $env:userprofile/.ubuntu/04_create_shortcut.ps1


打开 Ubuntu 目录:从这些说明下方复制命令 将命令粘贴到 PowerShell 按“Enter”

cd c:\users\admin\.ubuntu


创建快捷方式:从这些说明下方复制命令 将命令粘贴到 PowerShell 按“Enter”

powershell.exe -file .\04_create_shortcut.ps1


在资源管理器中打开目录:从这些说明下方复制命令 将命令粘贴到 PowerShell 按“Enter”

explorer .


启动 Ubuntu 桌面:双击“Ubuntu”快捷方式


打开终端:点击左上角的“活动”在搜索栏中输入“终端”点击“终端”


禁用屏幕锁定:从这些说明下方复制命令 将命令粘贴到终端中 按“Enter”

gsettings set org.gnome.desktop.screensaver lock-enabled false


安装 Snap Store:从这些说明下方复制命令 将命令粘贴到终端中 按“Enter”

sudo snap install snap-store


于 2020-12-11T01:52:28.750 回答
1

发现现在为了让 GUI 正常工作(至少在在线时),您需要使用您的公共 IP...

例如运行以下应该可以工作:

export DISPLAY=$(dig +short myip.opendns.com @resolver1.opendns.com):0
于 2020-09-23T04:14:38.127 回答
-3

这适用于 WSL1,为 WSL2 设置适当的 IP 地址

  1. 安装xming服务器
  2. 在 WSL 上运行 export DISPLAY=localhost:0.0

在此处输入图像描述

于 2021-01-14T15:25:04.783 回答
-6

如果有人不知道,有一个更简单的方法。2021 年,微软给了我们WSLg

您基本上只需要Windows 11 ,但建议使用 vGPU ( Intel AMD Nvidia )的驱动程序。

WSLg与 WSL1 不兼容。新的 WSL2 实例基本上可以正常工作™</a>。
旧的 WSL2 系统
需要更新一次:

  1. 在管理 PowerShell 中:wsl --update
  2. wsl --shutdown强制重启 WSL

不要忘记删除$DISPLAY您可能所做的任何其他修改!

在 Windows 11 上运行的 WSLg 的屏幕截图

于 2021-07-16T23:36:22.837 回答