67

Along with Windows 10 Anniversary update for summer 2016, came the possibility to run ubuntu binaries inside the new Windows Subsystem for Linux (WSL), a "lightweight" virtualized subsystem.

Unfortunately, launching C:\Windows\System32\bash.exe, another bash ELF binary starts a process inside the WSL, from where you cannot escape! You may launch only other ELF binaries.

So how can I execute *.exe files from Windows Bash?[1]

[1] Question asked also in Microsoft's "official" GH support repo.

1

6 Answers 6

63

In the Windows 10 Creators Update (build 1703, April 2017), this is natively supported. So you can now run Windows binaries from Linux...

notepad.exe or any other .exe (the extension is needed and it needs being on your path, some older versions need the whole path)

...and vice versa using one of the following:

  • bash.exe -c command_to_run i.e: bash.exe -c ls
  • bash -c command_to_run i.e: bash -c ls
  • wsl command_to_run i.e: wsl "ls"; or specify the distro you want to use to run it using:
    • ubuntu run ls

For more information, see the above linked article.

8
  • 3
    Might be worth pointing out that they changed the command from bash to wsl but it looks like bash still works but it might be deprecated. Commented May 16, 2018 at 5:05
  • 4
    note to others: you MUST include the extension and case-correct name on the exe for it to work. Commented Jan 11, 2019 at 9:10
  • I can't get that to work in general. For example, I have firefox installed (firefox.exe) but typing firefox.exe at the bash prompt results in firefox.exe: command not found Commented Mar 10, 2019 at 18:54
  • Oh I see: need to run /mnt/c/Program Files/Mozilla\ Firefox/firefox.exe Commented Mar 10, 2019 at 19:01
  • 2
    @xotonic calling windows exe's from WSL bash - you need to include the extension i.e. nodepad.exe Commented May 22, 2019 at 7:47
54

Native solution

The official solution provided with Windows 10 Insider Preview Update (14951) is based on the almost forgotten binfmt_msc Linux facility for launching binaries. The registration command for the binfmt_misc would be like this (where /init is the provisional binfmt_misc "interpreter" for the win-executables):

sudo echo ":WSLInterop:M::MZ::/init:" > /proc/sys/fs/binfmt_misc/register

And then win-executable would be launched like regular programs:

$ export PATH=$PATH:/mnt/c/Windows/System32
$ notepad.exe
$ ipconfig.exe | grep IPv4 | cut -d: -f2
$ ls -la | findstr.exe foo.txt
$ cmd.exe /c dir

Not that any win-executable must reside in the windows (DrvFs) file-system - not on the Linux's file-system (VolFs) - in order to inherit a proper Windows working-directory.

The cbwin alternative

Untill you get the latest build, project cbwin offers a workaround, by installing 3 new linux commands inside WSL:

  • wcmd: call a win-executable through cmd.exe.
  • wrun: call a win-executable synchronously with CreateProcess, and wait to die (not using cmd.exe).
  • wstart: launch a detached (asynchronously) command (with the use of cmd.exe).

In order to use them, you must:

  1. Install cbwin:
    • a new outbash.exe will be installed in your regular Windows filesystem (somewhere in your %PATH%), plus
    • the 3 linux-commands in the WSL filesystem.
  2. Use this outbash.exe (wherever you installed it) to start WSL, NOT C:\Windows\System32\bash.exe!
  3. Prefix any win-executables with one of those commands, e.g. wrun notepad.

Tip: If the executable launched with wcmd or wrun spawns any children, these survive only for as long that executable remains alive.

In other words, trying to start notepad.exe with wcmd won't work, because notepad will be killed just after having been launched -- Use wrun (synchronously) or wstart (asynchronously) in this case.

4
  • ouch! That's one heck of a work-around, but sometimes that's all we have (upvoted!) . Thanks for sharing.
    – shellter
    Commented Aug 12, 2016 at 14:48
  • 2
    With Creators Update (15063), running both command line and GUI exe just works fine. Commented Sep 24, 2017 at 2:45
  • 4
    I have to use echo ":WSLInterop:M::MZ::/init:" |sudo tee /proc/sys/fs/binfmt_misc/register, or it will say Permission denied. Commented Jul 14, 2021 at 18:47
  • but what about the opposite, what if I wanted a sort of binfmt_misc for windows to directly run ELF executables on Windows ? Commented Nov 15, 2023 at 17:26
5

why not just use

$ powershell.exe Start filename

Start is the Windows equivalent to xdg-open on most linux or open on macOS, which means "open with default desktop application". I like to alias it to open.

1
  • 1
    Note cmd.exe /c start is the same.
    – chx
    Commented Oct 11, 2021 at 0:27
4

I use alias.

alias aws="/mnt/c/Program\ Files/Amazon/AWSCLIV2//aws.exe"
alias kubectl="/mnt/c/ProgramData/chocolatey/bin/kubectl.exe"
alias kubectx="/mnt/c/ProgramData/chocolatey/bin/kubectx.exe"
alias kubens="/mnt/c/ProgramData/chocolatey/bin/kubens.exe"
alias pytest=pytest.exe
1
  • Did you know that Docker Desktop automatically adds kube commands to the WSL if you enable kubernetes support? Commented Dec 22, 2022 at 21:58
3

While running an .exe from the command line works, when running from say PHP via exec() I couldn't get that to work. Adding /init , however , does work. This is my working /usr/local/bin/convert file for GraphicsMagick installed on Windows:

#!/bin/sh
/init "$(ls /mnt/c/Program*/GraphicsMagick*/gm.exe|tail -1)" convert "$@"
0

I'm a bit baffled by this. I added a symlink:

$ ls -l /c                                                                                               
lrwxrwxrwx 1 root root 5 Dec  3 10:24 /c -> mnt/c  

now ls /c gives the same result as ls /mnt/c

But now: /c/Program\ Files/Java/jdk1.8.0_211/bin/java.exe -version ==> nothing

However:

/mnt/c/Program\ Files/Java/jdk1.8.0_211/bin/java.exe  -version 
java version "1.8.0_211"                                                                                                Java(TM) SE Runtime Environment (build 1.8.0_211-b12)                                                                   Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode) 

The same thing happens for other windows executables. Has WSL got a bug implementing symlinks?

3
  • I also tried this - created a symlink to the .exe directly, still no luck. Commented Mar 19, 2020 at 18:18
  • Another work around (a bit annoying) for a specific .exe create a proxy bash script - /mnt/d/path/to/executable.exe "$@" This was enough for me, i just wanted access to windows install of anaconda. Commented Mar 19, 2020 at 18:33
  • As of today, 2020-11-09, /c/Program\ Files/Java/jdk1.8.0_211/bin/java.exe -version gives me the exact output as having the /mnt.
    – xpt
    Commented Nov 10, 2020 at 2:38

Not the answer you're looking for? Browse other questions tagged or ask your own question.