SendKeys не работает из фоновой задачи

Исходная проблема:
Я использую в офисе внешнюю клавиатуру, поэтому я хочу включить 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

person BWhite    schedule 30.11.2017    source источник
comment
Как это вопрос, связанный с С#?   -  person Sir Rufo    schedule 01.12.2017
comment
@SirRufo Система предложила тег, когда я добавил одну строку C #. Я добавил его, потому что код С# тоже не работал. Но я согласен, что это не место.   -  person BWhite    schedule 03.12.2017


Ответы (1)


Так работает безопасность Windows. Это не имеет ничего общего с ключами отправки как таковыми, но задачи в разных контекстах безопасности не могут влиять на другие задачи.

Как видите, он работает при запуске в том же контексте безопасности, что и запускается только при входе пользователя.

Это называется изоляцией процесса, и принцип заключается в том, что никто не может связываться с интерактивным пользователем из-за как безопасности, так и принципов пользовательского интерфейса.

person ACatInLove    schedule 01.12.2017