SendKeys不能从后台任务工作

时间:2017-11-30 21:10:28

标签: vbscript scheduled-tasks wsh

初步问题:
我在办公室使用外接键盘,所以我想要NumLock ON。但是当我在家时,我只是使用笔记本键盘,所以我得到数字而不是字母,我必须关闭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

因此脚本本身运行正常。

UPDATE2:在作为后台任务运行时看起来可能与没有Windows工作站有关。事实证明,DetectNumlockConsole.exe也无效。这是一个简单的c#app,它返回此行的结果

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

1 个答案:

答案 0 :(得分:0)

这就是Windows安全的工作原理。它与sendkeys本身无关,但不同安全上下文下的任务不会影响其他任务。

正如您所看到的那样,在与相同的安全上下文中运行时,只有在用户登录时才会运行

它被称为进程隔离,主要是没有人可以使用 安全性和UI主体的交互式用户。