Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Windows Subsystem for Linux (WSL) provides bidirectional interop between Windows and Linux. You can launch Linux commands from Windows processes, run Windows executables from within a Linux shell, share files across both file systems, and forward network connections. This page summarizes the key interop patterns and their trade-offs.
Important
WSL interop requires that WSL is installed and at least one Linux distribution is registered. Do not assume WSL is present — always check before calling wsl.exe or accessing \\wsl$\ paths. On systems where WSL is not installed, wsl.exe returns a non-zero exit code with an error message, and \\wsl$\ UNC paths fail to resolve.
Command-line interop
Run Linux commands from Windows
Use wsl.exe from any Windows shell (PowerShell, Command Prompt, or Windows Terminal) to execute Linux commands:
# Run a single command in the default distribution
wsl ls -la /home
# Run a command in a specific distribution
wsl -d Ubuntu-22.04 -- cat /etc/os-release
# Pipe Windows output into a Linux command
ipconfig | wsl grep "IPv4"
Run Windows executables from Linux
From within a WSL shell, call any Windows executable by its full name (including the .exe extension):
# Open File Explorer in the current Linux directory
explorer.exe .
# Run a PowerShell command from Linux
powershell.exe -Command "Get-Date"
# Pipe Linux output into a Windows command
cat /etc/hosts | clip.exe
Note
Windows executables called from WSL use the Windows PATH. The .exe extension is required — without it, the shell looks for a Linux binary.
Detect whether WSL is available
Before relying on WSL interop in your app or script, check availability:
# PowerShell: Check if wsl.exe exists and WSL is functional
try {
$wslStatus = wsl --status 2>&1
if ($LASTEXITCODE -eq 0) {
Write-Host "WSL is available"
} else {
Write-Host "WSL is installed but not functional"
}
} catch {
Write-Host "WSL is not installed"
}
// C#: Check WSL availability before use
var wslPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.System), "wsl.exe");
if (!File.Exists(wslPath))
{
// WSL is not installed — handle gracefully
return;
}
var process = Process.Start(new ProcessStartInfo
{
FileName = wslPath,
Arguments = "--status",
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
}) ?? throw new InvalidOperationException("Failed to start wsl.exe process.");
process.WaitForExit();
if (process.ExitCode != 0)
{
// WSL is installed but no distribution is registered
}
File system interop
Access Linux files from Windows
Use the \\wsl$\ (or \\wsl.localhost\) UNC path to access Linux file systems from Windows:
\\wsl$\Ubuntu-22.04\home\username\project
\\wsl.localhost\Ubuntu-22.04\home\username\project
Important
The \\wsl$\ path is only available when the WSL instance is running. If the distribution is shut down, the path does not resolve. Start the distribution first with wsl -d <distro-name> or use wsl.localhost which can auto-start the distribution on Windows 11.
Access Windows files from Linux
Windows drives are mounted under /mnt/ by default:
# Access C: drive
ls /mnt/c/Users/username/Documents
# Access D: drive
ls /mnt/d/projects
Performance considerations
| Operation | Performance | Recommendation |
|---|---|---|
Linux process reading Linux files (/home/...) |
Fast (native ext4) | Keep project files here for Linux-based tools |
Windows process reading Windows files (C:\...) |
Fast (native NTFS) | Keep project files here for Windows-based tools |
Linux process reading Windows files (/mnt/c/...) |
Slow (cross-filesystem 9P protocol) | Avoid for build systems, node_modules, git repos |
Windows process reading Linux files (\\wsl$\...) |
Slow (cross-filesystem 9P protocol) | Use for occasional file access, not tight loops |
Tip
The most common performance mistake is storing project files on the Windows file system (/mnt/c/...) while running Linux build tools (npm, cargo, make). This causes significant I/O overhead. Instead, clone repositories into the Linux file system (~/projects/) when you primarily use Linux tools.
Path translation
Use wslpath inside WSL to convert between Windows and Linux paths:
# Windows path → Linux path
wslpath "C:\Users\username\file.txt"
# Output: /mnt/c/Users/username/file.txt
# Linux path → Windows path
wslpath -w /home/username/file.txt
# Output: \\wsl.localhost\Ubuntu-22.04\home\username\file.txt
# Linux path → Windows path (with drive letter format)
wslpath -m /mnt/c/Users/username/file.txt
# Output: C:/Users/username/file.txt
Networking interop
Localhost forwarding
By default, WSL 2 forwards ports from the Linux guest to localhost on Windows. A server running on port 3000 inside WSL is accessible from Windows at http://localhost:3000.
Note
Localhost forwarding works from Windows to WSL automatically on most Windows versions. However, connecting from WSL to a Windows-hosted server requires the Windows host IP (find it with cat /etc/resolv.conf | grep nameserver in older WSL configs, or use localhost directly if you have mirrored networking enabled).
Mirrored networking mode (Windows 11)
Windows 11 (version 22H2 and later) supports mirrored networking, where WSL shares the same network stack as Windows. Enable it in .wslconfig:
# %USERPROFILE%\.wslconfig
[wsl2]
networkingMode=mirrored
With mirrored mode:
- WSL and Windows share the same IP address
- Both can reach services on
localhostbidirectionally - VPN connections on Windows are automatically available in WSL
- IPv6 works inside WSL
Environment variable sharing
Pass Windows environment variables to WSL using the WSLENV variable:
# Windows: Share GOPATH with WSL (translate the path)
$env:WSLENV = "GOPATH/p"
$env:GOPATH = "C:\Users\username\go"
wsl echo $GOPATH
# Output: /mnt/c/Users/username/go
The /p flag translates Windows paths to Linux format. Other flags: /l (colon-separated list), /u (only WSL→Windows), /w (only Windows→WSL).
Common mistakes
Tip
Mistakes frequently produced by LLMs and code generators:
- Assuming
\\wsl$\is always accessible — the path only resolves while the target WSL distribution is running. Code that opens\\wsl$\paths without starting the distribution first fails with a network path error. - Not handling WSL-not-installed — many machines (especially Windows Server or enterprise-managed PCs) do not have WSL. Always check for
wsl.exeexistence before use. - Storing project files on the wrong file system — using
/mnt/c/for Linux projects or\\wsl$\for Windows projects causes severe I/O performance degradation due to 9P filesystem translation. - Hardcoding
/mnt/c/— the mount point is configurable in/etc/wsl.conf(via[automount] root). Usewslpathfor reliable path translation. - Forgetting
.exewhen calling Windows programs from WSL —notepadwon't work; you neednotepad.exe. This is a common copy-paste error from Windows-only documentation. - Assuming network topology — WSL 2 default (NAT) and mirrored modes have different network behaviors. Code that works on one developer's machine may fail on another depending on their
.wslconfigsettings. - Using WSL 1 assumptions for WSL 2 — WSL 1 shared the Windows network stack and had direct file system access. WSL 2 uses a lightweight VM with a virtual network adapter and 9P file sharing. Performance characteristics and networking are different.
Related content
Windows developer