win11开启linux图形子系统wslg

在windows设置中打开【启用或关闭Windwos功能】,勾选【适用于Linux的Windwos子系统】,点击确定后会系统会提示重启,选择确认即可 20220430130048

启用WSL

若是你输入wsl --set-default-version 2提示你请启用虚拟机平台 Windows 功能并确保在 BIOS 中启用虚拟化。

或者直接在power shell中执行

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

你还需要做两件事,第一个开启hyperv,第二个启用虚拟化

启用hyper-v

20220430134633

如果你是家庭版用户,可能找不到hyperv这个选项,可以使用以下方法突破hyperv

新建一个bat文件如下,使用管理员权限运行,可以在windows功能中找到hyperv

pushd "%~dp0"
dir /b %SystemRoot%\servicing\Packages\*Hyper-V*.mum >hyper-v.txt
for /f %%i in ('findstr /i . hyper-v.txt 2^>nul') do dism /online /norestart /add-package:"%SystemRoot%\servicing\Packages\%%i"
del hyper-v.txt
Dism /online /enable-feature /featurename:Microsoft-Hyper-V-All /LimitAccess /ALL

重启后在管理员powershell中执行一下命令

bcdedit /set hypervisorlaunchtype auto

BIOS启用虚拟化

20220430162400 20220430162411 20220430163226

组策略管理

本地计算机策略 > 计算机配置 > 管理模板>系统 > Device Guard 打开 基于虚拟化的安全设置为“已开启”或者“未设置”

安装linux

在CMD中输入命令wsl --set-default-version 2,更改新分发的默认安装版本,wsl版本第一代和第二代区别详情可以官网查看,此处建议使用 2

安装过程若是提示WslRegisterDistribution failed with error: 0x800701bc,则是老版本wsl需要更新到wsl2内核适用于 x64 计算机的 WSL2 Linux 内核更新包

wsl使用帮助

shell
# 设置默认版本2:
wsl --set-default-version 2
# 查看列表:
wsl -l -v
# 切换版本:
wsl --set-version CentOS7 2
# 关闭子系统:
net stop LxssManager
# 卸载子系统:
wsl --terminate CentOS8
# 注销子系统:
wsl --unregister CentOS8
# 导出系统镜像:
wsl --export CentOS7 D:\rootfs.tar

下载CentOS系统

这里使用是从github制作的 CentOS7 镜像,大小大约350M左右,点击直达,下载解压选择目录存放。也可以从Windwos商店直接安装其他发行版本(不建议直接在商店安装,因为无法选择安装位置,可以访这个地址,下载后改为zip解压后安装)

安装centos

在解压的文件夹中找到.exe文件,双击安装等待片刻会显示安装成功,同时当前文件夹生成一个【ext4.vhdx】的文件,该文件是centos的虚拟硬盘,但这里无法直接访问

同时在资源管理器右侧会多个【Linux】的目录,这个目录中存放的文件就是当前安装系统文件的根目录,Windows10没有这个快捷入口,可以在Win+R运行里输入\wsl.localhost访问目录 20220430132647

验证安装和使用

到这里基本已经安装完成了,在CMD中键入命令bash或者wsl即可进入子系统,使用cat /etc/redhat-release查看版本信息

启用图形化界面

修改源

一键配置镜像源,不配置可能下载会很慢。

mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
yum clean all
yum makecache
yum update -y

安装xce4

yum install -y sudo
yum install -y wget
sudo yum install -y epel-release
yum -y groupinstall Fonts # 安装字体 防止中文乱码
sudo yum groupinstall -y "Xfce" # 安装图形环境

启动桌面

startxfce4
yum install -y ibus-libpinyin # 安装输入法
# 安装完输入法后建议先重启 主机执行:wsl --shutdown 然后wsl启动
source ~/.bashrc
ibus-daemon & # 后台启动输入法

ibus-setup # 输入法配置

原生wslg图形界面

现在,可在完全集成的桌面体验中预览适用于 Linux 的 Windows 子系统 (WSL) 对在 Windows 上运行 Linux GUI 应用程序(X11 和 Wayland)的支持。

WSL 2 使 Linux GUI 应用程序在 Windows 上使用起来原生且自然。

  • 从 Windows 的“开始”菜单启动 Linux 应用
  • 将 Linux 应用固定到 Windows 任务栏
  • 使用 alt-tab 在 Linux 应用和 Windows 应用之间切换
  • 跨 Windows 应用和 Linux 应用剪切并粘贴

直接在appstore里搜索ubuntu,点击下载安装,注意安装界面选择english

OpenGL支持

sudo apt-get install build-essential libgl1-mesa-dev libglu1-mesa-dev libsoil-dev libglm-dev libassimp-dev libglew-dev libglfw3-dev libxinerama-dev libxcursor-dev libxi-dev libfreetype6-dev x11-apps mesa-utils

glxgears //测试OpenGL
glxinfo //gl信息

4k高分屏

如果使用的是4K高分屏,那么可以考虑安装 gnome-tweaks

第一步是打开命令行终端并确保我们在 Ubuntu 22.04 系统上启用了 Universe 存储库

备就绪后,执行以下命令在 Ubuntu 22.04 系统上安装 Tweak Tool

sudo add-apt-repository universe
sudo apt-get install gnome-tweaks

安装后运行 gnome-tweaks 命令,将Fonts的Scaling Factor提高,便可以在高分屏下显示大字体啦~

Windows和wsl相互访问

windows访问wsl

在 Windows 使用 localhost 可以直接访问 WSL 2 中运行的网络应用

wsl访问windows

/etc/resolv.conf中记录的wsl网卡地址,此地址即为windows地址,和windows共享端口

以在 WSL 2 (Ubuntu 18.04) 中使用 Windows 网络代理(此处为 socks5 代理)为例,向 ~/.bashrc 中写入以下内容:

export hostip=$(cat /etc/resolv.conf | grep -oP '(?<=nameserver\ ).*')

alias proxy='
export https_proxy="socks5://${hostip}:10808";
export http_proxy="socks5://${hostip}:10808";
export all_proxy="socks5://${hostip}:10808";
echo -e "Acquire::http::Proxy \"socks5h://${hostip}:10808\";" | sudo tee -a /etc/apt/apt.conf.d/proxy.conf > /dev/null;
echo -e "Acquire::https::Proxy \"socks5h://${hostip}:10808\";" | sudo tee -a /etc/apt/apt.conf.d/proxy.conf > /dev/null;
'

alias unproxy='
unset https_proxy;
unset http_proxy;
unset all_proxy;
sudo sed -i -e "/Acquire::http::Proxy/d" /etc/apt/apt.conf.d/proxy.conf;
sudo sed -i -e "/Acquire::https::Proxy/d" /etc/apt/apt.conf.d/proxy.conf;
'

在 bash 中运行 proxy 可设置 bash、apt 走代理,运行 unproxy 则关闭代理。

局域网其他机器访问wsl

要实现从局域网访问 WSL 2 网络,需要在 Windows 上配置 端口转发 和 防火墙允许入站规则。参考以下 PowerShell 命令(需以管理员权限执行):

# 查询 WSL 2 IP 地址
wsl -- hostname -I
172.20.147.252

# 配置端口转发:外网访问 windows 8080 端口转发到 172.20.147.252:8080
netsh interface portproxy add v4tov4 listenport=8080 connectaddress=172.20.147.252 connectport=8080

# 添加允许入站规则
New-NetFirewallRule -DisplayName "Allow Inbound TCP Port 8080" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 8080

Name : {0ff9eeaa-3e82-46f0-8b2a-cb985d514ede}
DisplayName : Allow Inbound TCP Port 8080
Description :
DisplayGroup :
Group :
Enabled : True
Profile : Any
Platform : {}
Direction : Inbound
Action : Allow
EdgeTraversalPolicy : Block
LooseSourceMapping : False
LocalOnlyMapping : False
Owner :
PrimaryStatus : OK
Status : 已从存储区成功分析规则。 (65536)
EnforcementStatus : NotApplicable
PolicyStoreSource : PersistentStore
PolicyStoreSourceType : Local

配置完后可在局域网用其他设备通过 Windows IP 访问 WSL 2 服务。

对应的删除配置命令:

netsh interface portproxy show v4tov4

侦听 ipv4: 连接到 ipv4:

地址 端口 地址 端口
--------------- ---------- --------------- ----------
* 8080 172.20.147.252 8080

# 删除端口转发规则
netsh interface portproxy delete v4tov4 listenport=8080

# 删除防火墙入站规则
Remove-NetFirewallRule -DisplayName "Allow Inbound TCP Port 8080"

将上诉命令封装成函数便于调用,向 PowerShell $PROFILE 配置文件写入函数:

# 在 PowerShell 中查看 $PROFILE 文件位置
$PROFILE
C:\Users\xxx\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

写入以下内容:

function Add-WSLPortProxy ($Port = '8080', $Protocol = 'TCP') {
$wslIP = wsl -- hostname -I
$wslIP = $wslIP.Trim()
netsh interface portproxy add v4tov4 listenport=$Port connectaddress=$wslIP connectport=$Port
New-NetFirewallRule -DisplayName "Allow ${Protocol} Inbound Port ${Port}" -Direction Inbound -Action Allow -Protocol $Protocol -LocalPort $Port
}

function Remove-WSLPortProxy ($Port = '8080', $Protocol = 'TCP') {
netsh interface portproxy delete v4tov4 listenport=$Port
Remove-NetFirewallRule -DisplayName "Allow ${Protocol} Inbound Port ${Port}"
}