2014-10-27 50 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中使用。