8

I installed Ubuntu 20.04 (server/terminal) from the Windows 10 Apps store. After launching the Ubuntu Terminal via WSL2 (Windows Subsystem for Linux), I installed Ubuntu Desktop and did several steps to try and get a desktop instance of Ubuntu 20.04 launched.

In short, the steps involved editing the .bashrc file, installing Xming, and then attempting to open the Ubuntu desktop in Xming with the startxfce4 command. However, startxfce4 just doesn't open the desktop for me. I can get programs to open with grun and the file explorer to open with gopen though, so it is working partially.

Does anyone have any alternative suggestions to how I might get the terminal to open up the full Ubuntu Desktop? Obviously, this wasn't what Windows had in mind with WSL2, so this is kind of a reach, but any input would be helpful. Could I somehow do this from the file explorer or with a program that could be opened from grun or gopen?

1
  • "startxfce4" starts the xfce4 or xubuntu desktop. If you installed ubuntu desktop it will not open that I think. I run Xubuntu and start the desktop with "startxfce4". Nov 15, 2020 at 16:01

3 Answers 3

12

My preferred approach for getting a "full desktop" under WSL is to use xrdp and then simply run Windows Remote Desktop Connection to enter the desktop manager. This avoids conflicts in hotkeys between Ubuntu and Windows. On the downside, it's a bit slower than using native WSLg.

The original question mentions both "Ubuntu Desktop" (assuming Gnome) as well as Xfce, so I'll provide steps for both. Xfce is the easier of the two, since it does not require Systemd.

Note that this updated answer has been tested on Ubuntu 22.10 with WSL2 version 1.0.3.

Xfce

sudo apt install xrdp xfce4
# If asked, select lightdm, although it probably doesn't matter

# Optionally, back up the default config
sudo cp /etc/xrdp/xrdp.ini /etc/xrdp/xrdp.ini.bak

# Windows Pro and higher are often already running RDP on 3389
# Prevent conflicts:
sudo sed -i 's/3389/3390/g' /etc/xrdp/xrdp.ini

# Prevent Wayland from being used in Xrdp
echo "export WAYLAND_DISPLAY=" > ~/.xsessionrc

# Optional, if you only have one desktop environment installed
echo startxfce4 > ~/.xsession 

sudo service xrdp start
# Or, if running Systemd
sudo systemctl restart xrdp

And that's it -- You should be able to connect to your WSL Desktop using the built-in Remote Desktop Connection app. The computer to connect to will be localhost:3390. Make sure Xorg is selected as the Session type.


Gnome Desktop

With the recent ability for WSL to use Systemd, this has become much more viable "out of the box". I'm not sure I'd "recommend it", but it's certainly possible.

First, enable Systemd. After restarting Ubuntu, ensure that Systemd is running via sudo systemctl status

The next few steps are similar to those for Xfce:

# Block ACPI features, which cause issues in WSL2, from being installed with Gnome
sudo apt-mark hold acpid acpi-support

sudo apt install ubuntu-desktop xrdp

# Optionally, back up the default config
sudo cp /etc/xrdp/xrdp.ini /etc/xrdp/xrdp.ini.bak

# Windows Pro and higher are often already running RDP on 3389
# Prevent conflicts:
sudo sed -i 's/3389/3390/g' /etc/xrdp/xrdp.ini

# Optional if you only have one desktop environment installed
echo gnome-session > ~/.xsession 

Create ~/.xsessionrc with the following:

export GNOME_SHELL_SESSION_MODE=ubuntu
export XDG_CURRENT_DESKTOP=ubuntu:GNOME
export XDG_DATA_DIRS=/usr/share/ubuntu:/usr/local/share:/usr/share:/var/lib/snapd/desktop
export WAYLAND_DISPLAY=
export XDG_CONFIG_DIRS=/etc/xdg/xdg-ubuntu:/etc/xdg

Then:

sudo systemctl restart xrdp

As with Xfce4, you should be able to connect to your Gnome Desktop using the built-in Remote Desktop Connection app. The computer to connect to will be localhost:3390. Make sure Xorg is selected as the Session type.

7
  • Installed gnome - works perfect. Thank you!
    – Nigrimmist
    Jan 11, 2023 at 22:03
  • When I do sudo -e ~/.xsessionrc, I keep getting the error editing files in a writable directory is not permitted, although I am a suoder on my local system
    – Avrana
    Feb 9, 2023 at 6:28
  • @Avrana Sorry about that! Someone else edited the answer a while back, and I tried to fix it (and broke it further). I've now just rolled it back to the original wording. You should just do this with your preferred text editor. I highly recommend learning vi if you don't know it, but new users may find nano to be easier. Feb 9, 2023 at 10:01
  • @NotTheDr01ds Can you give more details about using the built-in Remote Desktop Connection app? May 6, 2023 at 5:37
  • 1
    @S.Venkataraman Sure, what questions do you have? You should find it as a built-in application for Windows. When running it, you select localhost:3390 as mentioned in the answer, and you should then have access to Xfce4. May 7, 2023 at 17:14
7

I managed to get the full Ubuntu 20.04 Unity desktop GUI running using VcXsrv by installing the GNOME Desktop the ubuntu-wsl2-systemd-script and then appending a script to my ~/.bashrc file.

Initially, Ubuntu has root-only access, so create a normal account with sudo privileges:

sudo adduser username
sudo usermod -aG sudo username
exit

From now on, start WSL using that account:

wsl.exe -d distroname -u username

NOTE:
The ubuntu-wsl2-systemd-script calls systemd using --system-unit=basic.target and thus does not start the gdm or lightdm service, so edit the enter-systemd-namespace and start-systemd-namespace files and change --system-unit=basic.target to --system-unit=default.target prior to installation.

# runs only if 1st level shell
if [ $SHLVL = 1 ] &&
   [ -d "${srv_path="/mnt/c/Program Files/VcXsrv"}" ] &&
   [ -f "${srv_exec="$srv_path"/"${srv_name=vcxsrv.exe}"}" ] &&
   [ -d "${sys_path="/mnt/c/Windows/System32"}" ] &&
   [ -f "${tasklist="$sys_path"/tasklist.exe}" ] &&
   [ -f "${taskkill="$sys_path"/taskkill.exe}" ]; then
   # find a Windows Process ID
   function find_wpid {
     echo $("$tasklist" | grep "$1" | awk '{print $2; exit}')
     }
   # kill a Windows Process ID
   function kill_wpid {
     "$taskkill" /PID $1 /F /T >/dev/null
     }
   # export the Windows %UserProfile% path in Linux Format
   export WIN_HOME="$(wslpath "$($sys_path"/cmd.exe" /c "<nul set /p=%UserProfile%" 2>/dev/null)")"
   # Find the current WSL2 local IP address
   srv_addr="$(ip route | awk '{print $3; exit}')";
   # shutdown old instance of VcXsrv if running
   if [ "${gfx_wpid=$(find_wpid $srv_name)}" ]; then
     kill_wpid $gfx_wpid
     unset gfx_wpid
   fi
   # start a new instance of VcXsrv
   "$srv_exec" :0 -ac -wgl -fullscreen -notrayicon -dpms &
   # wait for startup success
   while [ -z $gfx_wpid ]; do gfx_wpid=$(find_wpid $srv_name); done
   # Start Windows Pulse Audio if installed
   unset srv_exec srv_name 
   if [ -f "${srv_exec="$srv_path"/pulse/bin/"${srv_name="pulseaudio.exe"}"}" ]; then
      # shutdown old instance of Pulse if running
      if [ ${snd_wpid=$(find_wpid $srv_name)} ]; then
        kill_wpid $snd_wpid
        unset snd_wpid
      fi
      # delete the expired Pulse config
      if [ -d "${snd_conf=$WIN_HOME"/.config/pulse"}" ]; then
        rm -r "$snd_conf"
      unset snd_conf
      fi
      # Start a new instance of Pulse
      "$srv_exec" --use-pid-file=false --disable-shm=true --exit-idle-time=-1 &
      while [ -z $snd_wpid ]; do snd_wpid=$(find_wpid $srv_name); done
      export PULSE_SERVER=tcp:"$srv_addr";
   fi
   # setup Ubuntu Desktop
   export DISPLAY="$srv_addr":0; 
   # setting below: 0 = llvmpipe (faster), 1 = software rasterizer
   export LIBGL_ALWAYS_INDIRECT=0
   export XDG_CONFIG_HOME=$HOME/.config
   export XDG_CONFIG_DIRS=/etc/xdg/xdg-ubuntu:/etc/xdg
   export XDG_SESSION_DESKTOP=ubuntu
   export XDG_SESSION_TYPE=x11
   export XDG_CURRENT_DESKTOP=ubuntu:GNOME
   export XDG_SESSION_CLASS=user
   export XDG_DATA_DIRS=/usr/share/ubuntu:/usr/local/share/:/usr/share/:/var/lib/snapd/desktop
   # cleanup expired vars
   unset tasklist sys_path srv_path srv_exec srv_name srv_addr
   # script stays here until gnome-session logout or failure
   gnome-session
   # shutdown VcXsrv
   if [ $gfx_wpid ]; then
     kill_wpid $gfx_wpid
     unset gfx_wpid 
   fi
   # shutdown Pulse
   if [ $snd_wpid ]; then
     kill_wpid $snd_wpid
     unset snd_wpid
   fi
   unset taskkill
   # shutdown the shell
   exit 0
fi

NOTE:
When all is up and running, go to Ubuntu's Settings -> Privacy -> Screen Lock and turn off the screen lock options. Trying to log back in after a screen lock for some reason results in an infinite loop when asking for your password. If that happens, just shutdown the WSL distro and on next start all is OK again.

Optional Audio Support

Download and unpack mingw64-pulseaudio-13.0.7z. Edit the \mingw\etc\pulse\default.pa file and replace line 38 containing load-module module-waveout sink_name=output source_name=input with:

load-module module-waveout sink_name=output source_name=input record=0
load-module module-native-protocol-tcp listen=0.0.0.0 auth-anonymous=1

Save the changes, rename the mingw folder as pulse and move it into your C:\Program Files\VcXsrv folder.
I am unsure if this step is required, however I also installed these apps via...

sudo apt-get install alsa-tools-gui pavumeter pavucontrol

Internet access is not immediately available unless you log out of your WSL2 Ubuntu Desktop and log back in again. This has become handy for me as allows me time to copy across updates from my real Ubuntu to the WSL2 Ubuntu without re-downloading them.

1

This is end of 2023, WSL2, Ubuntu and GNOME is mature enough to start display manager automatically under basic.target when launching systemd. So, no need to modify ubuntu-wsl2-systemd-script. Below is a complete self-contained solution of WSL2 + Ubuntu GNOME connected via X forwarding. Please note that this answer is for X forwarding. If you wish to use Windows Remote Desktop to connect GNOME, please follow the working instructions here.

Environment:

  • Host: Dell desktop PC, CPU: i5-4690, memory: 16GB DDR3
  • Windows: Windows 10 22H2, Education 64 bit, [Version 10.0.19045.3693]
  • WSL2: 2.0.9.0
  • Guest OS: Ubuntu 22.04.3 LTS
  • GUI desktop: GNOME 42.9
  • X server: VcXsrv 1.20.14.0

Solution:

  1. Install WSL + Ubuntu on a Windows machine of version 1903 or later (I am using 22H2).
    • Open Windows command line as Administrator. Run
      dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
      dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
      
      to enable Windows Subsystem for Linux and Virtual Machine features.
    • Restart Windows to apply the above step. This step cannot be skipped.
    • Download WSL2 update package from here and install it. If you did not restart in the above step, you would receive error "This update only applies to machines with the Windows Subsystem for Linux" and "Windows Subsystem for Linux Update Setup Wizard ended prematurely".
    • Open Windows command line (you don't need to be Administrator this time) and run wsl --install -d ubuntu
    • Input UNIX username (i.e., Ubuntu username) and password in the prompt.
  2. When WSL2 + Ubuntu installation is done, in Ubuntu command line, run
sudo apt update
sudo apt-mark hold acpid acpi-support
sudo apt upgrade
  1. Install GNOME: sudo apt install ubuntu-desktop gnome.
  2. Install ubuntu-wsl2-systemd-script:
cd ~
git clone https://github.com/DamionGans/ubuntu-wsl2-systemd-script.git
cd ubuntu-wsl2-systemd-script/
./ubuntu-wsl2-systemd-script.sh
  1. Exit WSL and Ubuntu by typing exit. In Windows command line, run
wsl --shutdown
wsl --update
wsl
  1. When you are back in the Ubuntu command line in WSL, export the following environment variables:
export DISPLAY="$(ip route | awk '{print $3; exit}')":0;
export XDG_CONFIG_HOME=$HOME/.config
export XDG_CONFIG_DIRS=/etc/xdg/xdg-ubuntu:/etc/xdg
export XDG_SESSION_DESKTOP=ubuntu
export XDG_SESSION_TYPE=x11
export XDG_CURRENT_DESKTOP=ubuntu:GNOME
export XDG_SESSION_CLASS=user
export XDG_DATA_DIRS=/usr/share/ubuntu:/usr/local/share/:/usr/share/:/var/lib/snapd/desktop
export GNOME_SHELL_SESSION_MODE=ubuntu
export XDG_RUNTIME_DIR="/run/user/1000"
sudo mkdir -p /run/user/1000
sudo chmod 700 /run/user/1000
sudo chown $(whoami): /run/user/1000

  1. Go to https://sourceforge.net/projects/vcxsrv/ to download VcXsrv Windows X Server. The version I am using is 1.20.14.0. Install it in Windows.
  2. Start VcXsrv by running XLaunch in Windows (if a previous VcXsrv is running, exit it. The settings of VcXsrv matter). Select "Fullscreen" in the first page. Fill up the "Additional parameters for VcXsrv" field in the third page with -ac -wgl -dpms.

When VcXsrv starts, you might see a whole black screen. That's the effect of full screen without contents yet. Press Alt-Tab to switch to Ubuntu command line in WSL.

  1. Run dbus-launch --exit-with-session gnome-session
  2. Go to the full-screen VcXsrv window. The Ubuntu GNOME desktop should show up now. Enjoy!
  3. You can just leave the GNOME alone when you don't use it. But if you really wanna quit GNOME, either close the VcXsrv window or press Ctrl-C on the Ubuntu command line in WSL.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .