重回Windows之对Linux的执念

起因

去年的差不多时候,我因为某些奇特操作将Windows系统搞炸之后转为使用Linux(NixOS)。原文在此

使用Linux这段时间能感觉到在对系统控制上比Windows自由得多,包管理也比Windows从网上下载 installer 安全省心得多,更重要的是接触到了 FOSS,摆脱了 Windows 上到处找学习版的痛苦(有些软件真不值得付费)。

但是 Wayland + Nvidia 实在说不上稳定,Bug可以说是层出不穷;XWayland 在 Nvidia 上更是灾难,Pull Request 一年过去了仍然处于 Stale 状态……

不过这些并非是我直接换回 Windows 的原因,除了我现在研究的PE逆向工程非常依赖于 Windows 系统之外,最直接的原因是因为最近换了条坏内存结果把文件系统搞坏了😒……

一开始以为是Linux内核或者btrfs模块的一些与这条内存的不兼容,结果换了Win还是一样,既来之则安之,回到 Windows 的第一件事就是把在 Linux 上形成的操作习惯恢复一下!

迁移

没什么好说的,具体要备份的文件和去年换 Linux 的差不多,不过 Linux 上的 .config 几乎用不上了,Windows 每个应用都有自己存放 config 的风格(这也是我非常不喜欢 Windows 软件生态的一点)而且大部分 Linux 应用都没有 Windows Build(有例外后面会说到)

折腾

注:因为 Windows 上的配置管理堪称灾难,我没有用 git 进行管理,我只能直接把配置贴进文章里了,等我找到统一配置文件夹的方法之后会更新。

驱动 (Lenovo Vantage)

首先先把硬件驱动都给更新一遍,尤其是BIOS驱动,我已经落后了几十个版本了(

毕竟是联想笔记本,那就用联想家的驱动更新程序吧,没必要用别的了。

虚拟机 (Oracle VM VirtualBox)

换回 Windows 一个很大的理由是要做逆向,那么虚拟机必须先搞定(我才不会说是因为第二天要检查实验才得赶紧把环境恢复的)

原本虚拟机使用的是 QEMU + KVM,虚拟硬盘采用的是 QCOW2 格式,不想费劲转换格式,发现 VirtualBox 支持 qcow2 真是太好了,而且其还是 Freeware 更好了(byebye VMWare)

不过如果用 VirtualBox 的话,为了性能就不能开启 Hyper-V,就不能使用 WSL 了,不过既然 Powershell 都费劲配置了,那就入乡随俗用 Powershell 好了。

字体渲染 (Winaero Tweaker & BetterClearTypeTuner)

来 Windows 第一感觉就是字体太太太丑了,听说 Win11 的微软雅黑在高分屏上已经可以看了,但是实际体验发现还是那个味。虽然雅黑的设计如此没办法,但我还是喜欢 Noto Sans 那样方正浓郁一点的屏显字体。

以前折腾的时候用过 MacType 优化字体渲染,但是其已经一年多不更新,没有明确支持 Win11 并且一直觉得这个软件的优化效果过于激进不太稳定,遂放弃。

好在发现了更好的方法:注册表直接进行字体替代,为了更好的进行备份恢复,我使用了一个软件 Winaero Tweaker。这个软件包含了很多注册表 Tweaks,而且能够方便地恢复,对系统修改的侵入性不强。

Advanced Apperance Settings -> Change System Font,修改系统字体为自己喜欢的 Sans 中文字体。

个人推荐:Noto Sans CJK SC, Sarasa UI SC, Glow Sans SC, PingFang SC,这几个字体我在高分屏(3840x2160, 28”)上都试过,个人感觉除了某些古老Win32应用因为字体字重太低导致发虚,苹方(PingFang SC)是最舒服的选择,因人而异。

然后就是不符合时代的 ClearType 了,ClearType 原本是就是为低分屏而生,在高分屏上反而显得没那么重要。但是!据我所测,如果不是微软雅黑这种带 Hint 的字体,比如说苹方在关闭 ClearType(采用灰阶抗锯齿)之后会出现字宽不统一的问题,而且开启后在高分屏上影响也不大。不过如果想要比较精确的调整 ClearType 的属性,可以用 BetterClearTypeTuner 对其设置。个人采用 FontAliasing + RGB + Contrast 2200,对比度我其实看不出什么区别……

命令行 (Windows Terminal & oh my posh! & scoop)

Linux 上用的是 kitty + fish,Windows上当然是 Windows Terminal + Powershell 了。

oh my posh!

不过 Powershell 外观不太好设置,跟 oh my zsh 类似,pwsh 也有 oh my posh 对 Prompt 进行外观上的配置。

omp 配置我使用了 zsh 最常用的 powerlevel10k_rainbow:

1
oh-my-posh init pwsh --config "$env:POSH_THEMES_PATH/powerlevel10k_rainbow.omp.json" | Invoke-Expression

ZLocation

autojump 虽然有 Windows Build,但是亲测不好用,可以用专门用于 pwsh 的 ZLocation,命令行中用 z 就可以使用(不过 autojump 和 ZLocation 貌似都不能记忆访问过的位置自动进行权重排序,不知道是不是 Powershell 自身安全保护问题)

scoop / winget / Chocolatey

与 Linux 百花齐放的包管理器生态不同,Windows 生态下命令行安装包常用的大概也就 4 种:winget / scoop / Chocolatey / Powershell Module,之所以使用 scoop 的原因主要是其安装包到 ~/scoop/ 下不会影响到其他程序。不过用哪个都差不多,看你想要安装的程序支持哪个(

https://github.com/ScoopInstaller/Scoop

helix

都费劲调 pwsh 了,不给 Windows 加上一个命令行文本编辑器怎么行,发现 Linux 上一直用的 helix 有 Windows Build:

1
scoop install helix

然后就可以使用之前在 Linux 上的配置啦~(不过我这个版本的 helix 好像读不了 %AppData%\helix\config.toml 我就只好在 pwsh 的 profile (相当于 .bashrc / .zshrc)中加上自定义的 Alias 了,最后的 $PROFILE 如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
# Add ZLocation
Import-Module ZLocation

# Enable AutoComplete Menu
Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete

# Init OMP with custom config
oh-my-posh init pwsh --config "C:\Users\$env:USERNAME\.config\ohmyposh\omp.json" | Invoke-Expression

# helix custom config hack
function hx([string]$file) {
helix -c C:\Users\$env:USERNAME\.config\helix\config.toml $file
}

这个过程可能不止这些操作,笔者也没有记录下全过程,总之 enjoy the ZheTeng~

平铺窗口管理器 (komorebi & whkd)

Linux 上最后一直使用 Hyprland 作为 Window Manager,想在 Windows 上复现平铺窗口,寻找一番后决定使用基于 Rust 的 komorebi

komorebi 与 Hyprland 功能类似,Workspaces / Window Rules / Hotkeys(whkd实现) 都有。

不过因为微软没有公开虚拟桌面相关API文档,komorebi 的工作区并没有采用虚拟桌面,而大概是记忆窗口所处的位置信息实现的,加上没有动画效果用起来感觉有一些些不跟手。

配置如下:

komorebi.json:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"app_specific_configuration_path": "$Env:USERPROFILE/applications.yaml",
"window_hiding_behaviour": "Cloak",
"cross_monitor_move_behaviour": "Insert",
"unmanaged_window_operation_behaviour": "NoOp",
"alt_focus_hack": true,
"mouse_follows_focus": false,
"default_workspace_padding": 2,
"default_container_padding": 2,
"active_window_border": false,
"monitors": [
{
"workspaces": [
{ "name": "I", "layout": "BSP" },
]
}
]
}

whkdrc:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
.shell powershell

# Reload whkd configuration
# alt + o : taskkill /f /im whkd.exe && start /b whkd # if shell is cmd
alt + o : taskkill /f /im whkd.exe ; Start-Process whkd -WindowStyle hidden # if shell is pwsh / powershell
alt + shift + o : komorebic reload-configuration

# Custom shortcuts
alt + x : komorebic stop
alt + q : komorebic close # kill active window shortcut because f4 is too far
alt + f : komorebic toggle-float
alt + shift + f : komorebic toggle-monocle
alt + return : Start-Process -FilePath "powershell" -ArgumentList "/noexit /nologo /c cd ~"
alt + r : komorebic retile
alt + z : komorebic minimize
alt + shift + z : komorebic toggle-maximize

# Workspaces
alt + 1 : komorebic focus-workspace 0
alt + 2 : komorebic focus-workspace 1
alt + 3 : komorebic focus-workspace 2
alt + 4 : komorebic focus-workspace 3
alt + 5 : komorebic focus-workspace 4
alt + 6 : komorebic focus-workspace 5
alt + 7 : komorebic focus-workspace 6
alt + 8 : komorebic focus-workspace 7

# Move windows across workspaces
alt + shift + 1 : komorebic move-to-workspace 0
alt + shift + 2 : komorebic move-to-workspace 1
alt + shift + 3 : komorebic move-to-workspace 2
alt + shift + 4 : komorebic move-to-workspace 3
alt + shift + 5 : komorebic move-to-workspace 4
alt + shift + 6 : komorebic move-to-workspace 5
alt + shift + 7 : komorebic move-to-workspace 6
alt + shift + 8 : komorebic move-to-workspace 7

启动器 (PowerToys Run)

Linux 有 fuzzel / rofi, Windows 有 PowerToys Run(PowerToys神中神),不过感觉就反应速度以及模糊搜索上不如 fuzzel。

状态栏 (yasb)

毕竟 Windows 有 Taskbar 和 Task Manager,类似 waybar / ewww 的程序挺少的,不过因为使用了 komorebi 和 PowerToys Run,TaskBar 唯一作用就是打开托盘图标菜单。这是需要一个可以显示时钟之类的状态栏。我使用的是比较简单的 yasb 而没有使用 Rainmeter,主要是我感觉 Rainmeter 太重了。

yasb 配置:

style.css:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
* {
font-family: 'Sarasa Term SC Nerd';
font-size: 16px;
font-weight: 600;
-webkit-font-smoothing: antialiased;
color: #f2e5bc;
}

.bar {
background: rgba(29, 32, 33, 0.3);
padding: 0 10px 0 10px;
}

.container-right .widget {
margin: 2px;
border-radius: 5px;
}

.container-right .widget * {
color: #f2e5bc;
}
.komorebi-workspaces {
margin-left: 0;
}
.ws-btn {
padding: 5px;
background: rgba(60, 56, 54, 0.4);
border: 1px solid rgba(168, 153, 132, 0.4);
margin: 2px 1px;
border-radius: 3px;
}

.ws-btn:hover {
color: #fbf1c7;
font-weight: bold;
}

.ws-btn.populated {
border-color: rgba(168, 153, 132, 1.0);
color: #ebdbb2;
}

.ws-btn.active {
background: rgba(251, 241, 199, 0.85);
color: #121212;
}

.custom-widget {
padding: 2px 6px;
color: #f2e5bc;
}
.custom-widget .icon {
font-size: 24px;
color: #f2e5bc;
}

.custom-widget .icon.icon-left {
margin-right: 5px;
}
.custom-widget .icon.icon-right {
margin-left: 5px;
}

.custom-widget.terminal-widget {
font-size: 16px;
}

.cpu-widget .label,
.wifi-widget .label,
.memory-widget .label,
.battery-widget .label {
padding: 2px 5px;
color: #f2e5bc;
border-radius: 5px;
}

.battery-widget,
.memory-widget {
margin: 0;
}

.active-window-widget {
margin-left: 5px;
}
.active-window-widget .label {
padding: -5px 7px 0 7px;
color: #f2e5bc;
margin-bottom: -1px;
border-radius: 3px;
margin: 2px;
}

.komorebi-active-layout .label {
color: #fbf1c7;
margin: -4px 2px 2px 8px;
font-family: Hack;
}

config.yaml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
watch_stylesheet: true
watch_config: true

bars:
yasb-bar:
enabled: true
screens: ['*']
class_name: "yasb-bar"
alignment:
position: "top"
center: false
blur_effect:
enabled: true
acrylic: true
dark: true
window_flags:
always_on_top: false
windows_app_bar: true
dimensions:
width: "100%"
height: 28
padding:
top: -1
left: 0
bottom: 0
right: 0
widgets:
left: ["komorebi_workspaces", "komorebi_active_layout", "active_window"]
center: ["clock"]
right: ["weather", "cpu", "memory", "battery"]

widgets:
active_window:
type: "yasb.active_window.ActiveWindowWidget"
options:
label: "{win[title]}"
label_alt: "[class_name='{win[class_name]}' exe='{win[process][name]}' hwnd={win[hwnd]}]"
label_no_window: ""
max_length: 48
max_length_ellipsis: "..."
monitor_exclusive: false

battery:
type: "yasb.battery.BatteryWidget"
options:
label: "{icon} {percent}%"
charging_options:
icon_format: "{charging_icon} {icon}"
time_remaining_natural: true

clock:
type: "yasb.clock.ClockWidget"
options:
label: "{%H:%M:%S}"
label_alt: "{%Y-%m-%d %H:%M:%S %Z}"
timezones: ["Asia/Shanghai", "Europe/London", "America/New_York"]
callbacks:
on_middle: "exec explorer.exe shell:Appsfolder\\Microsoft.WindowsAlarms_8wekyb3d8bbwe!App"
on_right: "next_timezone"

cpu:
type: "yasb.cpu.CpuWidget"
options:
label: "\uf200 {info[percent][total]}% | {info[freq][current]:.0f} Mhz"
# label: "\uf200 CPU: {info[percent][total]}% | freq: {info[freq][current]:.2f} Mhz"
#label_alt: "\uf200 {info[histograms][cpu_percent]} {info[percent][total]}%"
#label_alt: "\uf200 freq: {info[freq][current]:.2f} Mhz"
update_interval: 1000
histogram_icons:
- '\u2581' # 0%
- '\u2581' # 10%
- '\u2582' # 20%
- '\u2583' # 30%
- '\u2584' # 40%
- '\u2585' # 50%
- '\u2586' # 60%
- '\u2587' # 70%
- '\u2588' # 80%+
histogram_num_columns: 10
callbacks:
on_right: "exec cmd /c Taskmgr"

memory:
type: "yasb.memory.MemoryWidget"
options:
label: "\uf538 {virtual_mem_free} / {virtual_mem_total}"
label_alt: "\uf538 {virtual_mem_percent}%"
update_interval: 5000
callbacks:
on_right: "exec cmd /c Taskmgr"

komorebi_workspaces:
type: "komorebi.workspaces.WorkspaceWidget"
options:
label_offline: "Komorebi Offline"
label_workspace_btn: "{index}"
label_default_name: "{index}"
label_zero_index: false
hide_empty_workspaces: false

komorebi_active_layout:
type: "komorebi.active_layout.ActiveLayoutWidget"
options:
hide_if_offline: false
label: "{icon}"
layout_icons:
bsp: "[\\\\]"
columns: "[||]"
rows: "[==]"
vertical_stack: "[V]="
horizontal_stack: "[H]="
ultrawide_vertical_stack: "||="
monocle: "[M]"
maximised: "[X]"
floating: "><>"
paused: "[P]"
callbacks:
on_left: 'next_layout'
on_middle: 'toggle_monocle'
on_right: 'prev_layout'

wifi:
type: "yasb.wifi.WifiWidget"
options:
label: "{wifi_icon} {wifi_name}"
label_alt: "{wifi_icon} {wifi_name}"
update_interval: 5000
wifi_icons:
- "\udb82\udd2e" # 0% strength (no wifi)
- "\udb82\udd1f" # 1-25% strength
- "\udb82\udd22" # 26-50% strength
- "\udb82\udd25" # 51-75% strength
- "\udb82\udd28" # 76-100% strength. Alternate theming: \uf1eb
callbacks:
on_middle: "do_nothing"
on_right: "exec cmd.exe /c start ms-settings:network"

# Some custom widgets

weather:
type: "yasb.custom.CustomWidget"
options:
label: "\uf0c2 Changsha {data[current_condition][0][temp_C]}\u00b0c"
label_alt: "\uf0c2 {data[current_condition][0][weatherDesc][0][value]}"
class_name: "weather-widget"
exec_options:
run_cmd: "curl.exe wttr.in/Changsha?format=j1"
# run every hour
run_interval: 3600000
return_format: "json"

任务栏调整 (ExplorerPatcher)

折腾到这时候 TaskBar 已经不是随时需要的东西了,所以可以设置自动隐藏,我喜欢把它放在屏幕左侧,但是Win11没法调整 TaskBar 位置,只能用 ExplorerPatcher 将任务栏设置为 Win10 版本再修改位置。

总结

Windows 美化的局限性还是蛮大的,但是也并非不可能,这是我最终配置的结果,个人挺满意的:

不逊于 Hyprland 的显示效果 ~

这几天回归 Windows 只能感叹:果然臭打游戏的还是用 Windows 好啊!