Catching Ctrl+C in Powershell (console) can be done in two methods posted here:
First:
[console]::TreatControlCAsInput = $true
while ($true)
{
write-host "Processing..."
if ([console]::KeyAvailable)
{
$key = [system.console]::readkey($true)
if (($key.modifiers -band [consolemodifiers]"control") -and ($key.key -eq "C"))
{
Add-Type -AssemblyName System.Windows.Forms
if ([System.Windows.Forms.MessageBox]::Show("Are you sure you want to exit?", "Exit Script?", [System.Windows.Forms.MessageBoxButtons]::YesNo) -eq "Yes")
{
"Terminating..."
break
}
}
}
}
Second:
while ($true)
{
Write-Host "Do this, do that..."
if ($Host.UI.RawUI.KeyAvailable -and (3 -eq [int]$Host.UI.RawUI.ReadKey("AllowCtrlC,IncludeKeyUp,NoEcho").Character))
{
Write-Host "You pressed CTRL-C. Do you want to continue doing this and that?"
$key = $Host.UI.RawUI.ReadKey("NoEcho, IncludeKeyDown")
if ($key.Character -eq "N") { break; }
}
}
But PowerShell_ISE is not considered as a console. It is considered as a GUI as Microsoft stated here:
Windows PowerShell Integrated Scripting Environment (ISE) is a graphical host application
When running one of the above function on PowerShell_ISE, an error pops up:
Capturing any keys other than Ctrl+C on GUI, such as PowerShell_ISE, is possible with this function (credit to Matt McNabb):
function Test-KeyPress
{
<#
.SYNOPSIS
Checks to see if a key or keys are currently pressed.
.DESCRIPTION
Checks to see if a key or keys are currently pressed. If all specified keys are pressed then will return true, but if
any of the specified keys are not pressed, false will be returned.
.PARAMETER Keys
Specifies the key(s) to check for. These must be of type "System.Windows.Forms.Keys"
.EXAMPLE
Test-KeyPress -Keys ControlKey
Check to see if the Ctrl key is pressed
.EXAMPLE
Test-KeyPress -Keys ControlKey,Shift
Test if Ctrl and Shift are pressed simultaneously (a chord)
.LINK
Uses the Windows API method GetAsyncKeyState to test for keypresses
http://www.pinvoke.net/default.aspx/user32.GetAsyncKeyState
The above method accepts values of type "system.windows.forms.keys"
https://msdn.microsoft.com/en-us/library/system.windows.forms.keys(v=vs.110).aspx
.LINK
http://powershell.com/cs/blogs/tips/archive/2015/12/08/detecting-key-presses-across-applications.aspx
.INPUTS
System.Windows.Forms.Keys
.OUTPUTS
System.Boolean
#>
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.Windows.Forms.Keys[]]
$Keys
)
# use the User32 API to define a keypress datatype
$Signature = @'
[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
public static extern short GetAsyncKeyState(int virtualKeyCode);
'@
$API = Add-Type -MemberDefinition $Signature -Name 'Keypress' -Namespace Keytest -PassThru
# test if each key in the collection is pressed
$Result = foreach ($Key in $Keys)
{
[bool]($API::GetAsyncKeyState($Key) -eq -32767)
}
# if all are pressed, return true, if any are not pressed, return false
$Result -notcontains $false
}
While($true){
if(Test-KeyPress -Keys ([System.Windows.Forms.Keys]::ControlKey),([System.Windows.Forms.Keys]::Z)){
break
}
}
It worked well with Ctrl+Z but with Ctrl+C it doesn't because Ctrl+C cancel the session before it capture it.
Any idea how to capture Ctrl+C on PowerShell_ISE ?