Исходная проблема:
Я использую в офисе внешнюю клавиатуру, поэтому я хочу включить NumLock. Но когда я дома, я просто использую клавиатуру ноутбука, поэтому вместо букв я получаю цифры, и мне приходится выключать NumLock.
Исходное решение: Приведенный ниже сценарий определяет одну или две клавиатуры и включает или выключает NumLock в зависимости от ситуации.
Новая проблема:
Это отлично работает из командной строки, но я хочу, чтобы это срабатывало при входе в систему и происходило автоматически. Когда я запускаю его из планировщика заданий в фоновом режиме, эта строка не работает:
Shell.SendKeys "{NUMLOCK}"
Он срабатывает, но не переключает блокировку. Об ошибках не сообщается.
ОБНОВЛЕНИЕ: если я планирую запускать его под своей учетной записью «только когда пользователь вошел в систему», тогда он работает, но показывает окно cmd. Если я запускаю его под своей учетной записью или под учетной записью SYSTEM с параметром «независимо от того, вошел ли пользователь в систему или нет», окно исчезает, но оно не работает.
Будь то из cmd или как запланированная задача, я получаю этот вывод, когда он должен переключить блокировку:
Microsoft (R) Windows Script Host Version 5.812
Copyright (C) Microsoft Corporation. All rights reserved.
Found HID Keyboard Device
Found HID Keyboard Device
numLock is OFF
Toggling Numlock
Так что сам скрипт работает корректно.
ОБНОВЛЕНИЕ 2: Похоже, это может быть связано с отсутствием станции Windows при работе в качестве фоновой задачи. Оказывается, DetectNumlockConsole.exe
тоже не работает. Это простое приложение С#, которое возвращает результаты этой строки.
numLock = Control.IsKeyLocked(Keys.NumLock);
Опять же, это работает при запуске «только когда пользователь вошел в систему», но не «независимо от того, вошел ли пользователь в систему или нет».
--------- скрипт vbs ---------- -
set OUT = WScript.StdOut
Set Shell=CreateObject("Wscript.Shell")
Dim KeyCount
KeyCount = 0
Computer = "."
'set NumLock = CheckState
Set WMIService = GetObject("winmgmts:\\" & Computer & "\root\cimv2")
Set Devices = WMIService.ExecQuery ("Select * From Win32_USBControllerDevice")
For Each Device in Devices
DeviceName = Device.Dependent
Quotes = Chr(34)
DeviceName = Replace(DeviceName, Quotes, "")
DeviceNames = Split(DeviceName, "=")
DeviceName = DeviceNames(1)
Set USBDevices = WMIService.ExecQuery ("Select * From Win32_PnPEntity Where DeviceID = '" & DeviceName & "'")
For Each USBDevice in USBDevices
'OUT.WriteLine USBDevice.Description ' Write description to command line to see what to look for
If InStr( LCase( USBDevice.Description ), "keyboard" ) <> 0 Then
KeyCount = KeyCount + 1
OUT.WriteLine "Found " & USBDevice.Description
End If
Next
Next
dim numLock
numLock = Shell.Run("DetectNumlockConsole.exe",0,True)
If (numLock = 0) Then
OUT.WriteLine "numLock is OFF"
Else
OUT.WriteLine "numLock is ON"
End If
' If we have a keyboard, and numlock is OFF
' Or we don't have a keyboard, and numlock is ON
' Then toggle it
If (((KeyCount > 1) AND (numLock = 0)) OR ((KeyCount = 1) AND (numLock = 1))) Then
Shell.SendKeys "{NUMLOCK}" ' *** Problem here, doesn't toggle **
OUT.WriteLine "Toggling Numlock"
End If