Mark Lucernas
May 01, 2021

WSL/WSL2 Workarounds

Clipboard

This workaround was inspired by Neovide clipboard issue with WSL/WSL2. Also works with terminal neovim as long as clipboard is set to unnamedplus.

curl -sLo/tmp/win32yank.zip https://github.com/equalsraf/win32yank/releases/download/v0.0.4/win32yank-x64.zip
unzip -p /tmp/win32yank.zip win32yank.exe > /tmp/win32yank.exe
chmod +x /tmp/win32yank.exe
sudo mv /tmp/win32yank.exe /usr/local/bin/

NOTE: it is important that your shell source win32yank.exe before other clipboard tool such as xclip for Neovim/Neovide to recognize it as the default system clipboard. Hence, it should be in /usr/local/bin directory.

set clipboard=unnamedplus

Ref:

Audio Fix

  1. Paste the following code in ~/.bashrc or ~/.profile
HOST_IP=$(host `hostname` | grep 192. | tail -1 | awk '{ print $NF }' | tr -d '\r')
export DISPLAY=$HOST_IP:0.0
export PULSE_SERVER=tcp:$HOST_IP
export NO_AT_BRIDGE=1
export LIBGL_ALWAYS_INDIRECT=1

# Workaround for WSL/WSL2 X Server not working
if grep -qE "(Microsoft|WSL)" /proc/version &>/dev/null; then
  #WSL1
  export DISPLAY="${DISPLAY:-localhost:0.0}"
  export PULSE_SERVER="${PULSE_SERVER:-tcp:127.0.0.1}"
elif grep -q "microsoft" /proc/version &>/dev/null; then
  # WSL2
  HOST_IP=$(host `hostname` | grep 192. | tail -1 | awk '{ print $NF }' | tr -d '\r')
  export DISPLAY=$HOST_IP:0.0
  export PULSE_SERVER=tcp:$HOST_IP
fi

Then run source ~/.bashrc or source ~/.profile

  1. Clean install pulseaudio in WSL
sudo apt-get remove --purge alsa-base pulseaudio
sudo apt-get install alsa-base pulseaudio
sudo apt-get -f install && sudo apt-get -y autoremove && sudo apt-get autoclean && sudo apt-get clean && sudo sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
  1. Download pusleaudio-5.0-rev18.zip and extract to C:\wsl\pulse or to any known path.

  2. Create a config.pa inside pulse directory C:\wsl\pulse and add the following lines

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

Test this setup by running: c:\wsl\pulse\pulseaudio.exe -F config.pa in Windows terminal or Powershell by administrator.

  1. Remove pulseaudio configs
sudo rm /etc/pulse/client.conf #or just make sure every line is commented by cat /etc/pulse/client.conf

rm -rf ~/.config/pulse/*
pax11publish -e -r
  1. Create .bat script and add the following to automate pulseaudio service.
:: --- Start Xserver --- ::

:: For Vcxsrv
:: start "" /B "C:\wsl\config.xlaunch"
:: For X410
start /B x410.exe /desktop

:: --- Start pulseaudio --- ::

start "" /B C:\wsl\pulse\pulseaudio.exe -F C:\wsl\pulse\config.pa

:: --- EXTRAS --- ::

:: Hide console after launching script
:: https://www.robvanderwoude.com/battech_hideconsole.php
C:\wsl\ConsoleState /Hide

Another option is to create a Windows service to run PulseAudio everytime Windows start. πŸ“„ Setting up pulseaudio in windows

Now everytime you run the script, it will run your Xserver and pulseaudio service.

Test if wsl has sounds:

paplay /usr/share/sounds/freedesktop/stereo/bell.oga

If none of these steps work, refer to the resources below. Consider editing /etc/pulse/default.pa as an extra step. Link below.

Ref:

Start Daemon Services Using With Task Scheduler

Start cron at Startup

  1. Create startup script.
echo "service cron start" | sudo tee /usr/local/bin/cronstart.sh
sudo chmod +x /usr/local/bin/cronstart.sh
  1. Create a file within /etc/sudoers.d/ with purpose to allow your $USER to execute cronstart by sudo without password.

Run and copy the output:

echo "$USER ALL=(ALL) NOPASSWD: /usr/local/bin/cronstart.sh"

Run sudo visudo -f /etc/sudoers.d/cronstart then paste the content of the output. Save the file and exit.

  1. Run cronstart.sh on Windows startup

METHOD 1: Using Task Scheduler (Recommended for administrator accounts)

Run (as admin if current account isn’t) Task Scheduler

Click Task Scheduler Library on the left and then Create Task… on the right to create new task.

  • General tab:
    • Name: Anything you want, like WSL service cron start
    • Choose the option Run whether user is logged or not.
    • Mark Do not store password and Run with highest privileges.
    • In the Configure for dropdown select Windows 10.
    • If you need to setup a task for another user click on the button Change User or Group
  • Triggers tab:
    • Click New to add a new trigger for this task.
    • In the Begin the task dropdown select At startup.
    • Within the Advanced settings you can check Delay task for 1 minute.
  • Actions tab:
    • Click New to add a new action for this task.
    • Pick Start a program for the action type and then enter C:\Windows\System32\wsl.exe as the program to run.
    • At Add arguments (optional) set this: sudo cronstart.sh.

METHOD 2: Using bat script in shell:startup folder.

Open Run, or Windows explorer, and paste shell:startup (on the address bar for Windows explorer).

Then create a file called cronstart.bat and paste the following:

C:\Windows\System32\wsl.exe sudo cronstart.sh

FINALLY

Reboot system, then open WSL terminal and use service cron status to check if cron is running.

Ref:


Resources