How WSL Lets Linux and Windows Executables Call Each Other
Running notepad.exe from a Bash prompt, or a Linux tool from Windows' own command line, works because of a specific interop layer translating between two completely different executable formats and process models.
Running notepad.exe from a WSL Bash prompt and having it actually launch feels unremarkable once you’ve used WSL for a while — underneath, it’s bridging two completely different executable formats and process models, and that bridge is specifically engineered, not incidental.
The two directions of interop
Linux calling Windows (running notepad.exe, explorer.exe, or any other Windows binary from a WSL shell) and Windows calling Linux (running a WSL command directly from PowerShell or cmd.exe via wsl <command>) are both supported, and both go through distinct interop mechanisms rather than one unified layer.
How Linux-to-Windows execution actually works
When you run a .exe from inside WSL, the WSL interop layer recognizes the Windows PE (Portable Executable) binary format and hands the actual execution off to the Windows side — the process genuinely runs as a native Windows process, with WSL bridging the working directory, arguments, and standard input/output streams between the two environments.
How Windows-to-Linux execution actually works
The wsl command, run from PowerShell or cmd.exe, launches the specified command inside the WSL2 Linux environment and pipes its output back to the calling Windows shell — genuinely useful for scripting scenarios that need to combine Windows-native and Linux-native tools within the same script or pipeline.
What actually gets translated in both directions
Beyond just launching the correct binary, the interop layer handles translating file paths (/mnt/c/Users/... on the Linux side corresponding to C:\Users\... on the Windows side, using the filesystem bridge covered elsewhere), environment variables, and exit codes — enough plumbing that piping a Windows command’s output into a Linux tool, or vice versa, generally works the way you’d expect from either side alone.
The wslpath utility for path translation specifically
wslpath -w /mnt/c/Users/name/file.txt
# outputs: C:\Users\name\file.txt
wslpath -u 'C:\Users\name\file.txt'
# outputs: /mnt/c/Users/name/file.txt
Because scripts crossing the interop boundary frequently need to convert a path from one side’s format to the other’s explicitly, wslpath exists specifically for this — a small utility, but one that comes up constantly in any script mixing Windows and Linux tooling.
Why this interop can be selectively disabled
/etc/wsl.conf
[interop]
enabled = false
Some use cases (security-sensitive environments, or setups deliberately wanting strict isolation between the Windows host and the Linux environment) may want to disable this interop entirely — a configuration option Microsoft built in specifically because tight host integration isn’t universally desirable for every WSL use case.
Why this interop layer is the feature that makes WSL feel different from a “real” VM
A traditional virtual machine keeps the guest OS meaningfully isolated from the host by default — WSL’s interop layer is what makes it feel like Linux and Windows tools are part of one unified environment rather than two separate machines you have to deliberately bridge yourself, which is arguably the single biggest usability difference between WSL and running Linux in a conventional VM.