Hi
I wrote a function that check if you are pressing or pressed Ctrl-Q from the last time the function run and if so exit the script
This is useful for example if you have a long loop and you want to have the option to stop it by pressing a key but unlike Ctrl-C do it in a controlled position at the end of the loop
So you can click Ctrl-Q, the loop will continue as normal until the end of the current loop and then stop
I used the [console]/$Host methods KeyAvailable and ReadKey() and it’s working grate but not in Powershell ISE
so I fund a workaround for ISE by using GetAsyncKeyState() instead in it
But the problem now is that if I Enter-PSSession this two solutions not working in there, GetAsyncKeyState() always return 0 and ReadKey return “Cannot see if a key has been pressed when either application does not have a console or when console input has been redirected from a file. Try Console.In.Peek.”
function Stop-IfKey
{
[CmdletBinding()]
param
(
[Parameter(Mandatory=$false, Position=0)]
[Switch]
$InitializeIse
)
if ($InitializeIse)
{
if (!('Win32Functions.Win32GetAsyncKeyState' -as [type]))
{
$Signature = '[DllImport("user32.dll")]public static extern short GetAsyncKeyState(int vKey);'
Add-Type -MemberDefinition $Signature -Name 'Win32GetAsyncKeyState' -Namespace Win32Functions
Add-Type -AssemblyName System.Windows.Forms
}
$null = [Win32Functions.Win32GetAsyncKeyState]::GetAsyncKeyState([Windows.Forms.Keys]::LControlKey)
$null = [Win32Functions.Win32GetAsyncKeyState]::GetAsyncKeyState([Windows.Forms.Keys]::RControlKey)
$null = [Win32Functions.Win32GetAsyncKeyState]::GetAsyncKeyState([Windows.Forms.Keys]::Q)
Return
}
$QuittingMassage = 'Quitting, user pressed control Q...'
if ($Host.Name -notin 'Windows PowerShell ISE Host')
{
#[console]::TreatControlCAsInput = $true # For Ctrl-C
if ([console]::KeyAvailable) # Or ($Host.UI.RawUI.KeyAvailable)
{
$key = [console]::readkey($true) # Or $key = $Host.UI.RawUI.ReadKey()
if (($key.modifiers -band 'control') -and ($key.key -eq 'Q'))
{
#Write-Warning -Message $QuittingMassage
#Exit
throw $QuittingMassage
}
}
}
else
{
if (([Win32Functions.Win32GetAsyncKeyState]::GetAsyncKeyState([Windows.Forms.Keys]::LControlKey) -or [Win32Functions.Win32GetAsyncKeyState]::GetAsyncKeyState([Windows.Forms.Keys]::RControlKey)) -and [Win32Functions.Win32GetAsyncKeyState]::GetAsyncKeyState([Windows.Forms.Keys]::Q))
{
#Write-Warning -Message $QuittingMassage
#Exit
throw $QuittingMassage
}
}
}
Stop-IfKey -InitializeIse
$collection = @(1..5)
foreach ($item in $collection)
{
'Loop {0}' -f $item
Start-Sleep -Seconds 5 # Do stuff
Stop-IfKey
}
'End'