PoshCode Logo PowerShell Code Repository

DEMO: Trap Ctrl+C by Joel Bennett 8 years ago
embed code: <script type="text/javascript" src="http://PoshCode.org/embed/542"></script>download | new post

This is a demo of one way you could implement handling Ctrl+C (CancelKeyPressed) without using PSEvent or PInvoke …

  1. function Trap-CtrlC {
  2.    ## Stops Ctrl+C from exiting this function
  3.    [console]::TreatControlCAsInput = $true
  4.    ## And you have to check every keystroke to see if it's a Ctrl+C
  5.    ## As far as I can tell, for CtrlC the VirtualKeyCode will be 67 and
  6.    ## The ControlKeyState will include either "LeftCtrlPressed" or "RightCtrlPressed"
  7.    ## Either of which will -match "CtrlPressed"
  8.    ## But the simplest thing to do is just compare Character = [char]3
  9.    if ($Host.UI.RawUI.KeyAvailable -and (3 -eq [int]$Host.UI.RawUI.ReadKey("AllowCtrlC,IncludeKeyUp,NoEcho").Character))
  10.    {
  11.       throw (new-object ExecutionEngineException "Ctrl+C Pressed")
  12.    }
  13. }
  14.  
  15. function Test-CtrlCIntercept {
  16.    Trap-CtrlC  # Call Trap-CtrlC right away to turn on TreatControlCAsInput
  17.    ## Do your work ...
  18.    while($true) {
  19.       $i = ($i+1)%16
  20.       Trap-CtrlC ## Constantly check ...
  21.       write-host (Get-Date) -fore ([ConsoleColor]$i) -NoNewline
  22.       foreach($sleep in 1..4) {
  23.          Trap-CtrlC ## Constantly check ...
  24.          sleep -milli 500; ## Do a few things ...
  25.          Write-Host "." -fore ([ConsoleColor]$i) -NoNewline
  26.       }
  27.       Write-Host
  28.    }
  29.    
  30.    trap [ExecutionEngineException] {
  31.       Write-Host "Exiting now, don't try to stop me...." -Background DarkRed
  32.       continue # Be careful to do the right thing here (or just don't do anything)
  33.    }
  34. }
  35.  
  36.  
  37.  
  38. ## Another way to do the same thing without an external function ....
  39. ## Don't use this way unless your loop is really tight ...
  40. ## If you use this and hit CTRL+C right after a timestamp is printed,
  41. ## you'll notice the 2 second delay (compared with above)
  42. function Test-CtrlCIntercept {
  43.    ## Stops Ctrl+C from exiting this function
  44.    [console]::TreatControlCAsInput = $true
  45.    ## Do your work here ...
  46.    while($true) {
  47.       $i = ($i+1)%16
  48.       write-host (Get-Date) -fore ([ConsoleColor]$i)
  49.       sleep 2;
  50.       ## You have to be constantly checking for KeyAvailable
  51.       ## And you have to check every keystroke to see if it's a Ctrl+C
  52.       ## As far as I can tell, for CtrlC the VirtualKeyCode will be 67 and
  53.       ## The ControlKeyState will include either "LeftCtrlPressed" or "RightCtrlPressed"
  54.       ## Either of which will -match "CtrlPressed"
  55.       ## But the simplest thing to do is just compare Character = [char]3
  56.       if ($Host.UI.RawUI.KeyAvailable -and (3 -eq [int]$Host.UI.RawUI.ReadKey("AllowCtrlC,IncludeKeyUp,NoEcho").Character))
  57.       {
  58.          Write-Host "Exiting now, don't try to stop me...." -Background DarkRed
  59.          break;
  60.       }
  61.    }
  62. }

Submit a correction or amendment below (
click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:


Remember me