How to elegantly create a Windows shortcut that starts a WSL program under X

Viewed 9650

I'm struggling a little to launch xfce4-terminal from my WSL installation under VcXsrv from a button on the Windows taskbar. I don't want any DOS box/console/terminal other than the xfce4-terminal when I'm done. I have it working, but man is it ugly. Does anybody have a cleaner way of doing this?

Here is what I got working: I created a windows shortcut on the Desktop with this target (all in one line, broken with newlines for readability here):

C:\Windows\System32\wscript.exe
    \\wsl$\Ubuntu-20.04\home\peter\bin\windows\startTerminal.vbs

startTerminal.vbs was inspired by from 10 Ways To Run Batch Files Silently And Hide The Console Window • Raymond.CC (one of the few solutions that didn't require installing a separate program for this!) and it contains:

CreateObject("Wscript.Shell").Run "C:\Windows\System32\wsl.exe -u peter --exec /home/peter/bin/windows/startTerminal.sh",0,True

and startTerminal.sh contains:

export DISPLAY=localhost:0.0
xfce4-terminal --command=/bin/zsh

Setting DISPLAY is apparently required, even though I set the DISPLAY environment in ~/.zshrc. wsl.exe apparently doesn't do that unless you run the login shell.

Once all of this is working, I can drag my shortcut to the taskbar and click on it there.

I count 3, three files cooperating to achieve this simple goal? Can I limit that to one or two without installing an external program?

3 Answers

Yes, I think you can do what I do in one shortcut file. I'll share what works for me then you'll have to fiddle for your program.

Try putting all your commands in the Target section of the Shortcut link file.

Step 1. Right click on desktop then New then Shortcut then name it (LaunchXFCE4)

Step 2. Right click LaunchXFCE4 select Properties

Step 3. Enter all your launch sequences in the Target section

Step 4. Right click LaunchXFCE4 select Pin to Taskbar

I'm launching Emacs 27.1 on WSL 2 with Ubuntu 20.10 on Windows 10 using this code which perhaps you can modify.

C:\Windows\System32\wsl.exe --distribution Ubuntu20 bash -c "export DISPLAY=$(ip route | awk '{print $3; exit}'):0 && export LIBGL_ALWAYS_INDIRECT=1 && export XCURSOR_SIZE=16 && setsid emacs"

The first export display is similar to your localhost:0.0 so replace it or try mine. Maybe your xfce4 replaces my emacs. Read this post about double ampersands. So possibly this

C:\Windows\System32\wsl.exe --distribution Ubuntu20 bash -c "export DISPLAY=localhost:0.0 && export LIBGL_ALWAYS_INDIRECT=1 && export XCURSOR_SIZE=16 && setsid xfce4-terminal --command=/bin/zsh"

Note, my VcXsrv starts when windows starts by putting a shortcut to config.xlaunch in my C:\Users\USERNAME\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup.

By the way, Microsoft will provide a GUI for WSL in a few months, according to their blog

GUI app support in WSL is becoming a reality! We are getting closer to an initial preview and happy to announce a preview release for Windows Insiders within the next couple of months.

I removed the need for a startTerminal.sh file by:

Editing startTerminal.vbs to contain:

CreateObject("Wscript.Shell").Run "C:\Windows\System32\wsl.exe -u peter bash -l -c xfce4-terminal",0,True

And then I created a ~/.bash_profile to set the $DISPLAY variable, which probably should've been done anyway:

$ cat .bash_profile
if [ -z "$DISPLAY" ]; then 
    export DISPLAY=:0
fi

So now there is the shortcut and a startTerminal.vbs that starts it up. It still isn't very elegant...

After experimenting with @Saj 's answer which did not work for me I resulted in the below:

C:\Windows\System32\wsl.exe --distribution Ubuntu-20.04 bash -c "export DISPLAY=$((route.exe print | Select-String 0.0.0.0 | select -first 1) -Split "\s+" | select -Index 4):0.0 && export LIBGL_ALWAYS_INDIRECT=1 && setsid emacs"

Note that my problem was that it could not use bash commands inside the parenthesis (grep, awk)

Environment: WSL2 on Windows 10

Related