I'm using the new WLS2 on Windows 10 Home. I noticed that, when I ran "npm", the "npm" from my Windows program files was executed instead of the Linux version.

When I tried to execute cmd.exe or notepad.exe from WSL2, I noticed those also work!

How is this possible? How is WSL2 able to run Windows executables?

Additionally, how can I force WSL2 to prioritize the Linux executables over the Windows ones in cases where they have the same names?

  • 4
    Why are you shocked this works? WSL is aware of the Windows file system. So why wouldn’t it be able to run a Windows executable? The NT kernel still exists.
    – Ramhound
    Feb 14, 2020 at 19:59
  • 2
  • 3
    By specifying full paths. Windows looks into the file to decide how to run it. From CreateProcess - the ONLY way to start a program, lpApplicationName [in] Pointer to a null-terminated string that specifies the module to execute. The specified module can be a Windows-based application. It can be some other type of module (for example, MS-DOS or OS/2) if the appropriate subsystem is available on the local computer.
    – Mark
    Feb 14, 2020 at 22:19
  • Because Microsoft wanted it to.
    – K7AAY
    Feb 15, 2020 at 0:08
  • 1
    Another interesting fact is for files without a Windows' file association CMD.exe will pass it to CreateProcess to see if it knows what to do with it. So CMD (but not Explorer) will run an executable (of any supported type) no matter what it is called.
    – Mark
    Feb 15, 2020 at 4:51

4 Answers 4


How is WSL2 able to run Windows executables?

The Windows executable (PE binary) is added as a binfmt_misc entry in WSL2. In simple words, binfmt_misc is a Linux kernel feature which allows arbitrary executable file formats to be recognized and passed to certain programs.

In WSL2, the init binary (from which every process is forked) register the Windows PE binary as a executable and make it executable by itself (i.e. the init). Here is a output of the PE binfmt entry:

cat /proc/sys/fs/binfmt_misc/WSLInterop
interpreter /tools/init
flags: F
offset 0
magic 4d5a

WSLInterop is just a name for the entry. The magic number 4d5a is MZ which is first two bytes of Windows PE executable. Assume this is a fingerprint with which init (the interpreter) recognizes PE binary.

Users can temporarily (until WSL is restarted) disable the registry with this command:

echo 0 | sudo tee /proc/sys/fs/binfmt_misc/WSLInterop

Further readings:

  • I just ran the command, and I can still call .exes from WSL2. Any ideas if something changed or if I might have overlooked something?
    – debuglevel
    Apr 16 at 8:06
  • There seem to be some issues regarding disabling interop: github.com/microsoft/WSL/issues/8932 Changing /etc/wsl.conf seems to work as of WSL, but piping into /proc/sys/fs/binfmt_misc/WSLInterop does not.
    – debuglevel
    Apr 16 at 8:15

It will run any executable (Windows or linux) that is in your $PATH environment variable. It searches the directories in order, so if you want to run the linux versions by preference, make sure those directories are before the windows directories in the path

  • why is WSL able to run windows executables? Feb 14, 2020 at 19:49
  • 4
    Because ultimately your still running Windows. While WSL 2 is running a Linux kernel it’s aware of Windows.
    – Ramhound
    Feb 14, 2020 at 20:00

bash is running as a pico process. When you try to run a program, the linux subsystem driver recognizes the request to run a process and calls ZwCreateUserProcess in the windows kernel, creating the windows process.

It can call the function because all system calls made by pico processes are translated into NT calls in kernel mode, both via LXCORE.SYS and the kernel, ntoskrnl.exe.

  • 1
    That’s no longer the case with WSL2 though, which is essentially a VM.
    – Daniel B
    Feb 18, 2020 at 7:12

Create an alias for the Linux apps you wish to prioritize over their Windows namesakes. For example:

alias foo='/path/to/bar'

You must log in to answer this question.

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