晚上,浅色模式要亮瞎我的双眼。手动切换深色太麻烦,现考虑自动化实现。
需求分析 程序应完成以下功能:
每日晚上定时自动从浅色转换为深色; 每日上午定时自动从深色转换为浅色; 电脑开机时检查当前颜色设置并自动切换。 可行性分析 系统环境 Windows 10 家庭版。 WSL: Ubuntu.
手动实现 手动设置选项路径为:
设置 个性化 选择颜色 (浅色 / 深色 / 自定义) 自动实现 图 1: 注册表编辑器 查阅资料可知,通过修改注册表值可以实现命令行下的颜色切换。例如以下代码(Powershell)可以将默认 App 模式
切换为深色。
1 2 3 4 5 reg.exe add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize" ` /v AppsUseLightTheme ` /t REG_DWORD ` /d 0 ` /f
其中AppsUseLightTheme
是所要修改的变量名。通过注册表编辑器可以看到,需要修改的变量为AppsUseLightTheme
和SystemUsesLightTheme
,如图 1 所示。
Windows 系统有个叫 “任务计划程序” 的东西,可以实现定时执行脚本。听起来和 Linux 的 cron 很像,不过该方法能够设置的最小的时间间隔就是一天,远没有 cron 的 1 分钟强大。如果使用该功能实现我的需求,则需要三条任务计划规则才能实现,好处是每条规则一行就能实现,也不需要自定义复杂的脚本。如果使用 WSL 的 cron,则每小时调用我的脚本程序就好。代价是需要自己实现被调用的脚本,但好处是可以通过修改脚本的方式调整触发事件。
伪代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 dark_time := 21 :30 light_time := 6 :30 cur_theme_mode := current theme mode now := current time. SUB sync_theme_mode(cur_mode, new_mode) IF cur_mode equals new_mode THEN RETURN ELSE Sync current mode to new mode. END IF END SUB IF now < dark_time AND now > light_timeTHEN sync_theme_mode(cur_theme_mode, light_theme_mode) ELSE sync_theme_mode(cur_theme_mode, dark_theme_mode) END IF
Shell 代码 Cron 部分:
1 2 3 0 * * * * /path/to/auto_dark_mode.sh @reboot /path/to/auto_dark_mode.sh
/path/to/auto_dark_mode.sh
: ****
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 #!/bin/bash time_dark=1230 time_light=390 time_now=$(date +'%H*60+%M' | bc) query () { /mnt/c/Windows/system32/reg.exe query \ "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize" \ /t REG_DWORD \ /f "LightTheme" | tr -d '\r' | grep "$1 " | awk '{print $3}' } cur_app_mode=$(query 'AppsUseLightTheme' ) cur_sys_mode=$(query 'SystemUsesLightTheme' ) set_mode () { local var="$1 " local -i mode="$2 " /mnt/c/Windows/system32/reg.exe add \ "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize" \ /v "$var " \ /t REG_DWORD \ /d $mode \ /f } sync_theme_mode () { new_mode="$1 " if [ "$cur_app_mode " != "$new_mode " ]; then set_mode "AppsUseLightTheme" $new_mode fi if [ "$cur_sys_mode " != "$new_mode " ]; then set_mode "SystemUsesLightTheme" $new_mode fi } get_target_theme_mode () { if [ $time_now -lt $time_dark -a $time_now -gt $time_light ]; then printf "0x1" else printf "0x0" fi } sync_theme_mode $(get_target_theme_mode)
Fin.