Question

J'ai cherché mais apparemment mon google foo est faible. Ce dont j'ai besoin, c'est d'un moyen d'inviter l'utilisateur à entrer dans la console, de laisser la requête expirer après un certain temps et de continuer à exécuter le script si aucune entrée n'entre. Autant que je sache, Read-Host ne le fournit pas. fonctionnalité. $ Host.UI.PromptForChoice () non plus, ni $ host.UI.RawUI.ReadKey (). Merci d’avance pour tous les conseils.

EDIT: Merci beaucoup à Lars Truijens d’avoir trouvé la réponse. J'ai pris le code qu'il a signalé et encapsulé dans une fonction. Notez que la manière dont je l’ai implémenté signifie qu’il pourrait s'écouler une seconde de retard entre le moment où l'utilisateur appuie sur une touche et le moment où l'exécution du script se poursuit.

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

La solution

Vous avez trouvé quelque chose de ici :

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

Autres conseils

Il est assez ancien maintenant, mais voici comment j'ai résolu le problème en utilisant la même méthode KeyAvailable:

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

Il attend x secondes et affiche un . pour chaque seconde écoulée jusqu'au délai d'attente maximal. Si une touche est enfoncée, elle retourne $ true , sinon < $ 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;
}

Et pour utiliser:

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

Pour les personnes à la recherche d'une solution moderne avec une contrainte supplémentaire pour quitter un script PowerShell sur une touche prédéfinie, la solution suivante peut vous aider:

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

Exemple de sortie de script: entrer la description de l'image ici

Reportez-vous à Document Microsoft sur les états clés pour la gestion de plusieurs combinaisons.

Crédits: Lien Technet

Voici une fonction utilitaire de frappe qui accepte:

  • Jeu de caractères de validation (sous forme de regex à 1 caractère).
  • Message facultatif
  • Délai d'expiration facultatif en secondes

Seules les frappes de touche correspondantes sont reflétées à l'écran.

Utilisation:

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

Mise en oeuvre:

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})
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top