WSL (Windows Subsystem for Linux),是微软在Windows10中增加的Linux子系统,可以方便的在Windows中使用Linux系统进行开发、测试及其他便捷功能
当前有两个不同实现版本
以下表格为官方提供的两者功能对比
功能 | WSL 1 | WSL 2 |
---|---|---|
Windows 和 Linux 之间的集成 | ✅ | ✅ |
启动时间短 | ✅ | ✅ |
占用的资源量少 | ✅ | ✅ |
可以与当前版本的 VMware 和 VirtualBox 一起运行 | ✅ | ✅ |
托管 VM | ❌ | ✅ |
完整的 Linux 内核 | ❌ | ✅ |
完全的系统调用兼容性 | ❌ | ✅ |
跨 OS 文件系统的性能 | ✅ | ❌ |
简单归纳两者区别
不需要纠结,没啥特殊要求就上WSL2吧,而且两者可以相互转换
重要
重要
重要
WSL 2 现在有一项问题,如果使用了诸如 WeGame
的网络加速、Proxifier
等会改变网络设置的软件,会导致 WSL 2 无法启动
错误如下 参考的对象类型不支持尝试的操作。
使用管理员身份执行以下命令重置网络设置即可,无需重启计算机
netsh winsock reset
重要
重要
重要
以管理员身份在 CMD 或 PowerShell 中运行以下命令
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
或以管理员身份在 PowerShell 运行
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
该步骤是必须的,如果想使用 WSL 2 继续第2步,如果想使用 WSL 1 重启计算机
,然后直接跳到第5步。
WSL 2 使用了虚拟机技术,所以使用管管理员身份在 CMD 或 PowerShell 中运行以下命令
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
然后重启计算机
在 适用于 x64 计算机的 WSL2 Linux 内核更新包 中下载安装更新包
以管理员身份在 CMD 或 PowerShell 中运行下面的命令
wsl --set-default-version 2
将默认版本改为 WSL 2,以后安装wsl时将默认安装为 WSL 2,该版本可以随时转换
打开 Microsoft Store 选择自己喜欢的分发版进行安装
首先下载离线安装包
Ubuntu 20.04
Ubuntu 20.04 ARM
Ubuntu 18.04
Ubuntu 18.04 ARM
Ubuntu 16.04
Debian GNU/Linux
Kali Linux
OpenSUSE Leap 42
SUSE Linux Enterprise Server 12
Fedora Remix for WSL
安装
有两种安装方式
Add-AppxPackage .\app_name.appx
PATH
中对于在线安装的或者下载安装包使用命令安装的,直接打开对应图标即可
对于手动解压的,需要进入解压目录打开对应的可执行文件,如分发版为 Debian 的打开 debian.exe
即可
等待一会儿待初始化完成后按照说明分别设置 用户名
、密码
即可使用
如果你的系统是 Windows 内部版本 18362 或更高版本,可以无损转换已经安装的 WSL 版本
查询已安装的 WSL 分发版
wsl --list --verbose
命令输出中展示了
name: 已安装分发版名字
state: 已安装分发版状态,可以简单理解为开机还是关机状态
version: 已安装分发版版本,即 WSL 版本
使用第一条命令中找到的 name
(假如名字是 Debian
) 执行以下命令
wsl --set-version Debian 2
wsl --set-version Debian 1
将下面代码复制保存到 xxx.js
文件中,双击即可添加/删除右键菜单
var WshShell = new ActiveXObject("WScript.Shell");
WshShell.CurrentDirectory = "..";
WshShell.RegWrite("HKCU\\Software\\Classes\\Directory\\Background\\shell\\wsl_here\\", "WSL Here", "REG_SZ");
WshShell.RegWrite("HKCU\\Software\\Classes\\Directory\\Background\\shell\\wsl_here\\command\\"
, "C:\\Windows\\System32\\wsl.exe", "REG_SZ");
分发版的名字
几个字改为 查询已安装的 WSL 分发版 中获取到的 name
,想要添加哪个分发版就改为哪一个var WshShell = new ActiveXObject("WScript.Shell");
WshShell.CurrentDirectory = "..";
WshShell.RegWrite("HKCU\\Software\\Classes\\Directory\\Background\\shell\\wsl_here\\", "WSL Here", "REG_SZ");
WshShell.RegWrite("HKCU\\Software\\Classes\\Directory\\Background\\shell\\wsl_here\\command\\"
, "C:\\Windows\\System32\\wsl.exe -d 分发版的名字", "REG_SZ");
var WshShell = new ActiveXObject("WScript.Shell");
WshShell.RegDelete("HKCU\\Software\\Classes\\Directory\\Background\\shell\\wsl_here\\command\\");
WshShell.RegDelete("HKCU\\Software\\Classes\\Directory\\Background\\shell\\wsl_here\\");
使用了Windows Terminal?
参考我的另一篇文章 Windows Terminal 配置+右键菜单+管理员权限
当前时间 2020-11-27 官方文档中显示尚未支持纯 IPV6 的访问
WSL 1 直接与 Windows 共用网络,只需要开放相应端口即可
WSL 2 使用了虚拟机,所以需要将端口映射到物理机上
inet
处的ip地址ip addr | grep eth0 | grep inet
WSL 1 直接使用 127.0.0.1 或者 localhost 即可访问
WSL 2 当前版本使用命令找到的 ip 或者 localhost 均可访问
官方文档中提供的方法为从 /etc/resolv.conf
文件中寻找 nameserver
即为Windows的ip
可以在 WSL 中使用如下命令
cat /etc/resolv.conf | grep nameserver
WSL2 直接访问 Windows 时可能会被防火墙拦截,可添加一条防火墙入站规则,放行 WSL2 虚拟网卡对 Windows 的所有访问。
使用管理员权限在 PowerShell 中执行以下命令添加
New-NetFirewallRule -Name "WSL2_IN_ALLOW" -DisplayName "WSL2网卡入站放行" -Direction Inbound -InterfaceAlias "vEthernet (WSL)" -Action Allow -Description "WSL2虚拟网卡访问Windows的流量全部放行"
需要将 WSL 的端口与 Windows 端口绑定,并且 WSL 2 每次分配到的地址可能不固定,所以需要多次设置
以管理员身份运行
netsh interface portproxy add v4tov4 listenport=[Windows端口] listenaddress=0.0.0.0 connectport=[WSL端口] connectaddress=[WSL的IP]
查看端口转发状态
netsh interface portproxy show all
删除端口转发
netsh interface portproxy delete v4tov4 listenport=4000 listenaddress=0.0.0.0
为了方便使用,提供如下脚本进行添加、删除、查看Windows与WSL2的端口转发,复制另存为 xxx.bat
双击打开使用
只有安装了 WSL 的系统下可用
@echo off
@title WSL2端口转发
:isAdmin
::判断当前是否有管理员权限
REG QUERY "HKU\S-1-5-19">NUL 2>&1||(powershell -Command "Start-Process '%~sdpnx0' -Verb RunAs"&&exit)
:start
cls
echo.
echo. ************************************************
echo. * 自动获取 WSL 2 的ip地址,绑定指定端口号
echo. * 方便局域网/广域网访问 WSL 2 内部应用
echo. *
echo. * 0. 退出
echo. * 1. 绑定端口号
echo. * 2. 查看已绑定端口号
echo. * 3. 删除已绑定端口号
echo. ************************************************
echo.
goto loopChoice
:loopChoice
set "choice=notChoice"
set /p choice="输入序号后回车: "
if "%choice%"=="0" goto exit
if "%choice%"=="1" set "nextStep=addForward" & goto loopPort
if "%choice%"=="2" goto showForward
if "%choice%"=="3" set "nextStep=delForward" & goto loopPort
echo. & echo 选择错误 & goto loopChoice
:loopPort
echo.
set "choice=notPort"
set /p choice="输入监听的端口号后回车: "
if "%choice%"=="0" goto exit
echo %choice%| findstr /v "[^0-9]">nul&& set "wsl2Port=%choice%" || set "choice=notPort"
if %wsl2Port% GTR 65535 set "choice=notPort"
if %wsl2Port% LSS 1 set "choice=notPort"
if "%choice%"=="notPort" echo. & echo 端口号输入错误 & echo. & goto loop
goto %nextStep%
:addForward
:: 添加新的端口转发
for /f "tokens=2" %%i in ('wsl -e ip addr ^| findstr eth0 ^| findstr inet') do (set wsl2ip=%%i)
for /f "tokens=1 delims=/" %%i in ('echo %wsl2ip%') do (set wsl2ip=%%i)
netsh interface portproxy add v4tov4 listenport=%wsl2Port% listenaddress=0.0.0.0 connectport=%wsl2Port% connectaddress=%wsl2ip% && echo 添加成功 || echo 添加失败
goto end
:delForward
:: 删除已经存在的端口转发
netsh interface portproxy delete v4tov4 listenport=%wsl2Port% listenaddress=0.0.0.0 && echo 删除成功 || echo 删除失败
goto end
:showForward
:: 显示已经绑定的端口转发
netsh interface portproxy show all
goto end
:end
echo. & echo 按任意键返回主菜单... & pause >NUL
goto start
:exit
exit