2014-10-27 49 views
2

我想写一个脚本来定期切换大写字母锁定键,但我也希望能够切换脚本,因为它会导致一些问题与其他功能(如ALT加Tab键,并在任务栏上滚来滚去的窗口看到预览)听Powershell的按键,但不要等待

剧本我至今是

:outer while($true){ 
    do{ 
    echo "Toggle with F12"; 
    $x = [System.Console]::ReadKey() 
    }while($x.Key -ne "F12") 
    while($true){ 
     $wsh = New-Object -ComObject WScript.Shell 
     $wsh.SendKeys('{CAPSLOCK}') 
     sleep 0.3 
     [System.Runtime.Interopservices.Marshal]::ReleaseComObject($wsh) 
     Remove-Variable wsh 
     if ($Host.UI.RawUI.KeyAvailable) { 
      $key = $Host.UI.RawUI.ReadKey() 
      if($key.Key -ne "F12"){ 
       break outer 
      } 
     } 
    } 
} 

脚本等待用户按F12后,然后一旦他们按下F12,我希望它开始切换大写锁定键0.3秒,直到用户再次按下F12。理想情况下,我希望在后台发生这种情况,但我不知道这是否可能。我不希望用户必须打开控制台窗口才能切换脚本。

这种方式现在运行,用户按下F12后脚本将切换大写锁定一次,然后退出。如果我在Remove-Variable之后删除了条件语句,那么脚本将按我的意愿运行,除了可以停止的唯一方式是如果控制台窗口关闭。

+0

你试过用if([Console] :: KeyAvailable) – 2014-10-27 19:07:09

+0

@MickyB我只是试过一些东西,但脚本没有终止。我很确定它与我的条件有关,它检查按下了哪个键。 '如果([控制台] :: KeyAvailable){$ 键= $ Host.UI.RawUI.ReadKey() 如果($键-eq “F12”){ 破外 } }' 我将密钥存储在$ key中,然后尝试查看$ key -eq“F12”,但这不起作用。 – Lighthat 2014-10-27 19:16:18

回答

5

这是一个尝试。顺便说一句,我改变了睡眠1秒,因此不闪的CapsLock太多而测试:

$continue = $true 
while($continue) 
{ 

    if ([console]::KeyAvailable) 
    { 
     echo "Toggle with F12"; 
     $x = [System.Console]::ReadKey() 

     switch ($x.key) 
     { 
      F12 { $continue = $false } 
     } 
    } 
    else 
    { 
     $wsh = New-Object -ComObject WScript.Shell 
     $wsh.SendKeys('{CAPSLOCK}') 
     sleep 1 
     [System.Runtime.Interopservices.Marshal]::ReleaseComObject($wsh)| out-null 
     Remove-Variable wsh 
    }  
} 
+0

我不得不做一个小小的改动,以便在切换时不会退出,但是,这很好。你知道是否有任何方法让它在后台监听,以便在没有控制台窗口成为焦点的情况下切换它? – Lighthat 2014-10-27 22:03:56

+0

即使您没有焦点,您也可以创建一个钩子(通过SetWindowsHookEx)来捕获键盘事件。不过,我不知道你是否可以在PowerShell中实现本地化。您可能必须在C#中执行此操作并添加您的代码。 – 2014-10-28 03:32:40

1

add-type -Path '.\documents\WindowsPowerShell\VISE_WinKeyboardHook.dll' 
 
$KeyboardInterceptor = new-object VISE.WinKeyboardHook.KeyboardInterceptor 
 
function HandleKeyDown($keyId) 
 
{ 
 
    write-host $keyID.KeyCode 
 
    if($keyID.KeyCode -eq "Escape"){ 
 
     $KeyboardInterceptor.StopCapturing() 
 
    } 
 
} 
 
Unregister-Event -SourceIdentifier KeyDown -ErrorAction SilentlyContinue 
 
$keyevent = Register-ObjectEvent -InputObject $KeyboardInterceptor -EventName KeyDown -SourceIdentifier KeyDown -Action {HandleKeyDown($event.sourceEventArgs)} 
 
$KeyboardInterceptor.StartCapturing()

这里是一个C#组件,其全球keybord事件提供事件。 https://ianmorrish.wordpress.com/v-ise/keyboard-hook/ 这样做的好处是它是非阻塞的,并且也可以在ISE中使用。