需要电脑已经安装Lenovo Vantage, 如果按下Fn+空格
能够切换键盘灯则已经安装.
仅在ThinkBook 15 2021款测试过, 其他机型可能略有不同甚至不受支持.
较旧的机型使用其他方式控制键盘灯, 脚本并未做支持.base_path
各个系统可能不同, 可以尝试自行寻找有IdeaNotebookPlugin.dll
和Contract_Keyboard.dll
的目录.timeout
单位为秒.
将代码保存为Powershell脚本(.ps1
)并设置开机自动启动即可, 无需管理员特权.
PowerShell脚本:
$base_path = "C:\ProgramData\Lenovo\ImController\Plugins\IdeaNotebookPlugin\x64"
$timeout = 15
Add-Type -Path ($base_path + "\IdeaNotebookPlugin.dll")
Add-Type -Path ($base_path + "\Contract_Keyboard.dll")
$assembly = [System.Reflection.Assembly]::LoadFrom($base_path + "\IdeaNotebookPlugin.dll")
$agent = $assembly.GetTypes()[0].GetMethod("GetInstance").Invoke($null,$null)
$list = New-Object -TypeName Lenovo.Modern.Contracts.Keyboard.SettingList
$request = New-Object -TypeName Lenovo.Modern.Contracts.Keyboard.KeyboardSettingsRequest
$request.List = $list
$item = New-Object -TypeName Lenovo.Modern.Contracts.Keyboard.Setting
$list.Items.Add($item)
$item.key = "KeyboardBacklightStatus"
Add-Type @'
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace PInvoke.Win32 {
public static class UserInput {
[DllImport("user32.dll", SetLastError=false)]
private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
[StructLayout(LayoutKind.Sequential)]
private struct LASTINPUTINFO {
public uint cbSize;
public int dwTime;
}
public static DateTime LastInput {
get {
DateTime bootTime = DateTime.UtcNow.AddMilliseconds(-Environment.TickCount);
DateTime lastInput = bootTime.AddMilliseconds(LastInputTicks);
return lastInput;
}
}
public static TimeSpan IdleTime {
get {
return DateTime.UtcNow.Subtract(LastInput);
}
}
public static int LastInputTicks {
get {
LASTINPUTINFO lii = new LASTINPUTINFO();
lii.cbSize = (uint)Marshal.SizeOf(typeof(LASTINPUTINFO));
GetLastInputInfo(ref lii);
return lii.dwTime;
}
}
}
}
'@
function GetBacklightStatus {
$level = $agent.GetBacklightStatus()
return ($level.List.Items | where { $_.key -eq "KeyboardBacklightStatus" }).value;
}
$state = 1
$level = GetBacklightStatus
while (1) {
Start-Sleep -Milliseconds 500
$idle = [PInvoke.Win32.UserInput]::IdleTime.TotalSeconds
if($idle -gt $timeout) {
if ($state -eq 0) { continue }
$state = 0
$level = GetBacklightStatus
$item.value = "off"
} else {
if ($state -eq 1) { continue }
$state = 1
if ((GetBacklightStatus) -ne "off") { continue }
$item.value = $level
}
Write-Host "Dispatch"
$agent.SetBacklightStatus($request)
}