Pregunta

He buscado pero aparentemente mi google foo es débil. Lo que necesito es una forma de solicitar la entrada del usuario en la consola y tener el tiempo de espera de la solicitud después de un período de tiempo y continuar ejecutando el script si no entra ninguna entrada. Por lo que puedo decir, Read-Host no proporciona esto funcionalidad Ni $ host.UI.PromptForChoice () ni $ host.UI.RawUI.ReadKey (). Gracias de antemano por cualquier puntero.

EDITAR: Muchas gracias a Lars Truijens por encontrar la respuesta. Tomé el código que él señaló y lo encapsulé en una función. Tenga en cuenta que la forma en que lo he implementado significa que podría haber hasta un segundo de retraso entre el momento en que el usuario toca una tecla y la continuación de la ejecución del script.

function Pause-Host
{
    param(
            $Delay = 1
         )
    $counter = 0;
    While(!$host.UI.RawUI.KeyAvailable -and ($counter++ -lt $Delay))
    {
        [Threading.Thread]::Sleep(1000)
    }
}
¿Fue útil?

Solución

Encontré algo aquí :

$counter = 0
while(!$Host.UI.RawUI.KeyAvailable -and ($counter++ -lt 600))
{
      [Threading.Thread]::Sleep( 1000 )
}

Otros consejos

Es bastante antiguo ahora, pero cómo lo resolví con el mismo método KeyAvailable está aquí:

https://gist.github.com/nathanchere/704920a4a43f06f4f0d2

Espera x segundos, mostrando un . por cada segundo que transcurre hasta el tiempo máximo de espera. Si se presiona una tecla, devuelve $ true ; de lo contrario, $ false .

Function TimedPrompt($prompt,$secondsToWait){   
    Write-Host -NoNewline $prompt
    $secondsCounter = 0
    $subCounter = 0
    While ( (!$host.ui.rawui.KeyAvailable) -and ($count -lt $secondsToWait) ){
        start-sleep -m 10
        $subCounter = $subCounter + 10
        if($subCounter -eq 1000)
        {
            $secondsCounter++
            $subCounter = 0
            Write-Host -NoNewline "."
        }       
        If ($secondsCounter -eq $secondsToWait) { 
            Write-Host "`r`n"
            return $false;
        }
    }
    Write-Host "`r`n"
    return $true;
}

Y para usar:

$val = TimedPrompt "Press key to cancel restore; will begin in 3 seconds" 3
Write-Host $val

Para las personas que buscan una solución de la era moderna con una restricción adicional para salir de un script de PowerShell al presionar una tecla predefinida, la siguiente solución podría ayudarlo:

Write-Host ("PowerShell Script to run a loop and exit on pressing 'q'!")
$count=0
$sleepTimer=500 #in milliseconds
$QuitKey=81 #Character code for 'q' key.
while($count -le 100)
{
    if($host.UI.RawUI.KeyAvailable) {
        $key = $host.ui.RawUI.ReadKey("NoEcho,IncludeKeyUp")
        if($key.VirtualKeyCode -eq $QuitKey) {
            #For Key Combination: eg., press 'LeftCtrl + q' to quit.
            #Use condition: (($key.VirtualKeyCode -eq $Qkey) -and ($key.ControlKeyState -match "LeftCtrlPressed"))
            Write-Host -ForegroundColor Yellow ("'q' is pressed! Stopping the script now.")
            break
        }
    }
    #Do your operations
    $count++
    Write-Host ("Count Incremented to - {0}" -f $count)
    Write-Host ("Press 'q' to stop the script!")
    Start-Sleep -m $sleepTimer
}
Write-Host -ForegroundColor Green ("The script has stopped.")

Salida de script de muestra: ingrese la descripción de la imagen aquí

Consulte Documento de Microsoft sobre estados clave para manejar más combinaciones.

Créditos: Enlace de Technet

Aquí hay una función de utilidad de pulsación de tecla que acepta:

  • Conjunto de caracteres de validación (como una expresión regular de 1 carácter).
  • Mensaje opcional
  • Tiempo de espera opcional en segundos

Solo las pulsaciones de teclas coincidentes se reflejan en la pantalla.

Uso:

$key = GetKeyPress '[ynq]' "Run step X ([y]/n/q)?" 5

if ($key -eq $null)
{
    Write-Host "No key was pressed.";
}
else
{
    Write-Host "The key was '$($key)'."
}

Implementación:

Function GetKeyPress([string]$regexPattern='[ynq]', [string]$message=$null, [int]$timeOutSeconds=0)
{
    $key = $null

    $Host.UI.RawUI.FlushInputBuffer() 

    if (![string]::IsNullOrEmpty($message))
    {
        Write-Host -NoNewLine $message
    }

    $counter = $timeOutSeconds * 1000 / 250
    while($key -eq $null -and ($timeOutSeconds -eq 0 -or $counter-- -gt 0))
    {
        if (($timeOutSeconds -eq 0) -or $Host.UI.RawUI.KeyAvailable)
        {                       
            $key_ = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown,IncludeKeyUp")
            if ($key_.KeyDown -and $key_.Character -match $regexPattern)
            {
                $key = $key_                    
            }
        }
        else
        {
            Start-Sleep -m 250  # Milliseconds
        }
    }                       

    if (-not ($key -eq $null))
    {
        Write-Host -NoNewLine "$($key.Character)" 
    }

    if (![string]::IsNullOrEmpty($message))
    {
        Write-Host "" # newline
    }       

    return $(if ($key -eq $null) {$null} else {$key.Character})
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top