How to invoke and use Windows programs in WSL2
Learn how to run Windows binaries directly from the WSL terminal.
WSL2 is tightly integrated with the Microsoft Windows operating system, which allows it to run Linux applications alongside and even interop with other Windows desktop and modern store apps.
The good thing about WSL is that you can open Windows programs directly from bash. In addition, your Windows system environment Path variable is now appended to the WSL counterpart by default (you can check this by running echo $PATH
in WSL; you’ll notice there are many /mnt/c/
directories added to the Unix PATH variable).
This means you can now invoke notepad.exe
(or the name of any other app on your default Windows Path variable) without typing its absolute path! However, you must explicitly invoke a Windows binary with its .exe
extension for WSL to recognize the binary as a Windows executable.
Thus, you can also define your default Windows browser as the default Unix browser by configuring the $BROWSER
environmental variable in bash. I am using Brave here, but you can swap it with your own favorite browser. In other words, you can edit the~/.bashrc
or ~/.zshrc
file by adding the following line:
export BROWSER="/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe"
Now, when you open a Jupyter Notebook from within the WSL terminal, for example, it will automatically open the Brave browser installed on Windows. This way you save HD space by not having to install a new browser in Unix.
Running any Windows program in WSL
While WSL will automatically detect any Windows executables within the original Windows environment Path variable, it might be the case that you have installed a new Windows program and also want it to be detected. There are several ways to do this, but I will focus on the three best practices.
When you have a directory containing many Windows programs that you want to use in WSL, I suggest adding the entire directory to the PATH variable by modifying the
~/.bashrc
or~/.zshrc
file:
export PATH="$PATH:/mnt/c/path/to/desired directory"
Once this is done, we can invoke the Windows executable using the following command (remember to write the extension as well):
executable.exe
However, this method may have the inconvenience of closing the WSL terminal upon invoking the Windows executable (this behavior will depend on the executable). To avoid this, there are two alternatives.
The first uses Window’s Powershell to invoke the Windows executable (notice you have to write the full path to the executable according to its location in the Windows explorer):
powershell.exe -c C:/path/to/executable_name
However, we can add an alias to the ~/.bashrc
or ~/.zshrc
file to invoke Powershell more easily:
alias psh="powershell.exe -c"
In addition, we can add the folder containing executables directly to the Windows Path variable instead of the ~/.bashrc
or ~/.zshrc
file. This way we can invoke the executables without having to write the full path.
To add the folder to the Windows environment Path, hit Windows + R
, type sysdm.cpl
and hit enter. Go to the Advanced tab and click on Environmental variables. Find the Path variable in the System variables panel and add the desired folder to its list of paths. Now the folder will be directly imported to the Unix PATH variable every time you open a new WSL terminal.
Upon completing these steps, we can do the the following to invoke Windows executables (notice we don’t have to write the full path nor the extension):
psh executable_name
The last alternative to invoking Windows executables in the WSL terminal also involves adding an alias to the
~/.bashrc
or~/.zshrc
file, but has the disadvantage of having to create an alias for every single executable. That being said, this is my favorite method.
alias wpymol="\"/mnt/c/Program Files/path/to/pymol_executable.exe\""
Notice two important things:
- I added a “w” before the alias name to explicitly remember that I am invoking a Windows executable called “pymol”. This is not obligatory, but I have found to be a good practice.
- I added the
\
(backslash) before and after the the desired command to escape properly (if we remove the backslashes, the WSL terminal may also close upon invoking the executable).
Now we can simply do:
wpymol
That’s it! Cheers!