给 Windows Terminal 装上会看时间的皮肤:主题自动切换实战
【免费下载链接】terminalThe new Windows Terminal and the original Windows console host, all in the same place!项目地址: https://gitcode.com/GitHub_Trending/term/terminal
周五下午,你盯着发白的终端背景皱了皱眉,顺手打开「设置 > 个性化」,把应用模式从浅色切到深色——标题栏跟着变了,终端里却还是一片白。你盯着看了两秒,手动改了配色,然后决定:这件事以后不该靠手动。Windows Terminal 的主题自动切换要做的就是这一件事:让配色方案跟着系统深浅色主题走,或者按你设定的时间点自动变。
先看效果
做完之后你的终端会是这个样子:系统切到深色主题,终端配色跟着变深;切回浅色,它又变回来,全程不用碰鼠标。分屏场景下,每个窗格按各自的 profile 应用对应配色,互不打架。

它是怎么工作的(原理速览)
可以把它理解成给终端装了个"看天色自动换灯泡"的传感器:灯泡(配色方案)是你预先挂好的两盏,传感器就是系统主题状态,天黑了就自动换到深色那盏。机制本身很轻——终端只盯住系统主题这一个开关,开关一翻,就换到对应方案,不需要重启进程。
这个行为的设计出处在官方规范 doc/specs/#4066 - Theme-controlled color scheme switch.md,其中写明终端应当"根据所选主题自动切换配色方案,包括system主题的情况"。配置格式的规范则定义在 doc/cascadia/profiles.schema.json 的SchemePair类型里,light/dark两个字段各指一个已存在的配色方案名。
从零搭起来(核心操作)
整个过程只改你本地settings.json,仓库本身一个字都不动。
先把系统主题交给系统自己管
打开「设置 > 个性化 > 颜色」,把应用模式设为"自动",按日出日落切换。这一步是给终端的"传感器"通电——如果这里锁死在深色或浅色,后面终端侧配得再全也不会动。
给 colorScheme 换上双方案配置
按Ctrl+,打开设置文件(JSON),在profiles.defaults里加一个对象形式的colorScheme。之所以用对象而不是字符串,是因为字符串只能写死一个方案,对象才能同时挂住深浅两套:
// 自定义部分:深浅双方案,方案名必须与 schemes 里已有的一致 "profiles": { "defaults": { "colorScheme": { "light": "Campbell", "dark": "Campbell Powershell" } } }方案名写错了不会报错,终端会静默回退到默认方案——这是这个配置最容易翻车的地方,写之前对一眼schemes数组里的名字。
把整个应用交给 system 主题
顶层"theme"决定"传感器"读谁的信号。写成system后,终端跟随系统自动翻转;写light或dark则锁死,双方案配置形同虚设:
// 自定义部分:跟随系统主题 { "theme": "system", // ... }保存后新开的标签页立即生效;已经开着的窗口,等下一次系统主题翻转时自然跟上即可。如果到这里已经够用了——你只在乎"跟系统走"——后面进阶部分可以先跳过。
往深里走(进阶 / 场景化拓展)
固定时段切换:不依赖系统,按钟点换配色
有些人的作息跟日出日落不同步,比如夜班党或者下午才到工位的人。这种情况就别依赖系统主题了,用任务计划程序在固定时间点改本地配置。先建一个脚本(放在你自己目录里,别放仓库中):
# 按小时挑配色:时段和方案名都改成自己的 $hour = (Get-Date).Hour $scheme = if ($hour -ge 18 -or $hour -lt 6) { "Campbell" } elseif ($hour -ge 12) { "Campbell Powershell" } else { "Solarized Light" } $settingsPath = "$env:LOCALAPPDATA\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json" $settings = Get-Content $settingsPath -Raw | ConvertFrom-Json $settings.profiles.defaults.colorScheme = $scheme $settings | ConvertTo-Json -Depth 32 | Set-Content $settingsPath改的是你%LOCALAPPDATA%下的本地配置文件,仓库是只读的,跟它没有关系。脚本本身不定时,靠任务计划程序兜底:在"任务计划程序"里建基本任务,触发器设成每日 6:00 / 12:00 / 18:00 各一次,操作选"启动程序",程序填powershell.exe,参数指向脚本路径。
两种机制打架时,谁说了算
时间触发和系统主题同时存在时,脚本自己定个优先级。下面这段放在脚本开头:系统主题当前是深色就什么都不改,其余时段再按时间上方案——相当于把"系统"当第一裁判:
# 系统已切深色时不覆盖,其余时段按时间换 $theme = (Get-ItemProperty 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize').AppsUseLightTheme if ($theme -eq 0) { exit }再叠一层:电池供电时强制深色,护眼优先。
# 电池模式强制深色 $battery = Get-CimInstance Win32_Battery if ($battery.BatteryStatus -eq 1) { $scheme = "Campbell" # 换成你的深色方案 }| 场景 | 谁说了算 | 做法 |
|---|---|---|
| 系统主题已显式翻转 | 系统优先 | 脚本开头检测后直接exit |
| 固定工作时段 | 时间优先 | 脚本按小时覆盖colorScheme |
| 电池供电 | 深色优先 | 检测Win32_Battery后锁深色 |
分屏下让所有窗格一起变
配置改完后,想立刻看到效果又不想关窗口:命令面板(Ctrl+Shift+P)里输入 "Reload" 执行重载配置,所有分屏窗格会统一应用新配色,不会出现一半深一半浅的尴尬。

别踩这些坑(排错与注意事项)
版本太老,配了没反应?对象形式的colorScheme需要较新的 Windows Terminal 版本,老版本只认字符串。先跑一下wt --version确认,不行就升级到最新版。
改完 JSON 终端打不开了?十有八九是ConvertTo-Json把嵌套结构压扁、或引号转义错了。手改文件前先把settings.json复制一份备份,改完可以用任意 JSON 校验器过一遍再交给终端。
为什么方案没切过去,颜色一点没变?方案名和schemes数组里的名字差一个空格都会静默回退默认方案。对一下拼写,别信"没报错就是对的"。
亚克力和像素着色器要不要一起开?useAcrylic和experimental.pixelShaderPath都吃 GPU,低配设备或老核显上先别叠加,主题联动本身零开销。
脚本会不会把文件写坏?Set-Content是整体覆盖,写之前文件被终端重写(终端也会自动保存配置)可能互相踩一脚。脚本里先读一遍、校验是合法 JSON,再动手写。
最后说两句
配置联动是现成的,按钟点切是自己拼的,两条路都通了之后,剩下的就是挑几套顺眼的配色轮班。项目 roadmap 里"整体主题支持"(页签色、标题栏色、窗格边框色统一定义)和"主题市场"还在路上,见 doc/terminal-v2-roadmap.md——等这两样落地,主题切换的玩法会比现在宽得多。你的配色组合或踩坑心得,欢迎按 CONTRIBUTING.md 的指引去提 issue 聊聊。
【免费下载链接】terminalThe new Windows Terminal and the original Windows console host, all in the same place!项目地址: https://gitcode.com/GitHub_Trending/term/terminal
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考