Domanda

Ho cercato ma a quanto pare il mio google foo è debole. Ciò di cui ho bisogno è un modo per richiedere l'input dell'utente nella console e avere il timeout della richiesta dopo un periodo di tempo e continuare a eseguire lo script se non arriva alcun input. Per quanto posso dire, Read-Host non fornisce questo funzionalità. Né $ host.UI.PromptForChoice () né $ host.UI.RawUI.ReadKey (). Grazie in anticipo per eventuali suggerimenti.

EDIT: Mille grazie a Lars Truijens per aver trovato la risposta. Ho preso il codice che ha sottolineato e incapsulato in una funzione. Nota che il modo in cui l'ho implementato significa che potrebbe esserci fino a un secondo di ritardo tra il momento in cui l'utente preme una chiave e il completamento dell'esecuzione dello script.

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

Soluzione

Trovato qualcosa qui :

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

Altri suggerimenti

Adesso è piuttosto vecchio, ma il modo in cui l'ho risolto in base allo stesso metodo KeyAvailable è qui:

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

Attende x secondi, visualizzando un . per ogni secondo che trascorre fino al tempo di attesa massimo. Se viene premuto un tasto, restituisce $ true , altrimenti $ 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;
}

E da usare:

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

Per le persone che sono alla ricerca di una soluzione moderna con un ulteriore vincolo all'uscita da uno script di PowerShell con una pressione predefinita dei tasti, la seguente soluzione potrebbe essere d'aiuto:

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.")

Output dello script di esempio: inserisci qui la descrizione dell'immagine

Consultare Documento Microsoft sugli stati chiave per la gestione di più combinazioni.

Crediti: Collegamento Technet

Ecco un'utilità di battitura che accetta:

  • Set di caratteri di convalida (come regex di 1 carattere).
  • Messaggio opzionale
  • Timeout opzionale in secondi

Solo i tasti corrispondenti vengono riflessi sullo schermo.

Utilizzo:

$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)'."
}

Implementazione:

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})
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top