Comment faire une «pause» avec PowerShell 2.0?

113

OK, je le perds. PowerShell m'ennuie. Je voudrais qu'une boîte de dialogue de pause apparaisse, et ce ne sera pas le cas.

PS W:\>>> $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Exception calling "ReadKey" with "1" argument(s): "The method or operation is not implemented."
At line:1 char:23
+ $host.UI.RawUI.ReadKey <<<< ("NoEcho")
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException
Derrick Bell
la source
1
J'ai eu le même problème dans PowerShell ISE. Fonctionne bien dans la console PowerShell standard.
Charles Anderson
3
Je suis juste en train de jouer avec PowerShell et c'est toujours ennuyeux, même 2 ans et demi plus tard!
Bill K
Si vous lisez le lien Adam's Tech ou le code dans la réponse @Michael Sorens (environ à mi-chemin de la page au moment où j'écris ceci en 2020), vous découvrirez peut-être une technique pour envelopper votre pause if (!$psise) { <# pause #> }. Si vous êtes comme moi et que 99% de la raison pour laquelle vous voulez une pause est pour que vous puissiez lire l'écran avant qu'il ne clignote, cela vous aidera, car si vous êtes dans l'ISE, il ne clignote pas et vous ne 't need the pause
john v kumpf

Réponses:

88
cmd /c pause | out-null

(Ce n'est pas la méthode PowerShell, mais c'est tellement plus élégant.)

Sauver des arbres. Utilisez des one-liners.

Carlos Nunez
la source
7
/ c Exécute la commande spécifiée par string puis se termine | out-null redirige la sortie vers out-null, où vous ne la verrez jamais. Si vous voulez voir le message "Appuyez sur n'importe quelle touche pour continuer ...", supprimez le tube. En outre, cela ne semble pas fonctionner dans PowerShell ISE. Le processus est simplement bloqué et vous ne pouvez appuyer sur aucune touche. Un moyen de contourner cela?
Wouter
1
@Wouter Voir ce billet de blog: Comment mettre correctement en pause un script PowerShell
Nick
7
@Nick oui, 47 lignes de code pour remplacer "cmd / c pause | out-null", cela ressemble à la manière PowerShell.
Bill K
@BillK Le message que j'ai lié répond à la question de Wouter. Êtes-vous en désaccord?
Nick
6
Ce n'était pas un commentaire sur votre réponse, je pense que vous avez tout à fait raison. C'est un commentaire sur PowerShell. Je suis modérément dégoûté - je n'ai pas vu autant de verbosité obscurcissante inutile depuis que j'ai programmé en Cobol.
Bill K
234

Je pense qu'il vaut la peine de récapituler / résumer les choix ici pour plus de clarté ... puis proposer une nouvelle variante qui, à mon avis, offre la meilleure utilité.

<1> ReadKey (console système)

write-host "Press any key to continue..."
[void][System.Console]::ReadKey($true)
  • Avantage: accepte toutes les touches mais exclut correctement les touches de modification Maj, Alt, Ctrl.
  • Inconvénient: ne fonctionne pas dans PS-ISE.

<2> ReadKey (RawUI)

Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
  • Inconvénient: ne fonctionne pas dans PS-ISE.
  • Inconvénient: n'exclut pas les touches de modification.

<3> cmd

cmd /c Pause | Out-Null
  • Inconvénient: ne fonctionne pas dans PS-ISE.
  • Inconvénient: lance visiblement un nouveau shell / fenêtre lors de la première utilisation; pas perceptible lors d'une utilisation ultérieure mais a toujours les frais généraux

<4> hôte de lecture

Read-Host -Prompt "Press Enter to continue"
  • Avantage: fonctionne dans PS-ISE.
  • Inconvénient: n'accepte que la touche Entrée.

<5> composite ReadKey

Ceci est un composite de <1> ci-dessus avec la solution de contournement ISE / kludge extraite de la proposition sur Adam's Tech Blog (avec la permission de Nick à partir des commentaires précédents sur cette page). J'ai apporté deux légères améliorations à ce dernier: ajouté Test-Path pour éviter une erreur si vous utilisez Set-StrictMode (vous le faites, n'est-ce pas?!) Et le dernier Write-Host pour ajouter une nouvelle ligne après votre frappe pour mettre le invite au bon endroit.

Function Pause ($Message = "Press any key to continue . . . ") {
    if ((Test-Path variable:psISE) -and $psISE) {
        $Shell = New-Object -ComObject "WScript.Shell"
        $Button = $Shell.Popup("Click OK to continue.", 0, "Script Paused", 0)
    }
    else {     
        Write-Host -NoNewline $Message
        [void][System.Console]::ReadKey($true)
        Write-Host
    }
}
  • Avantage: accepte toutes les touches mais exclut correctement les touches de modification Maj, Alt, Ctrl.
  • Avantage: fonctionne dans PS-ISE (bien que seulement avec Entrée ou clic de souris)
  • Inconvénient: pas un one-liner!
Michael Sorens
la source
9
Meilleure réponse, surtout parce qu'elle fournit une solution qui fonctionne partout
Petr
Très bonne réponse! Je tiens à noter que l'ajout du AllowCtrlCparamètre au choix 2 permet à l'utilisateur de cliquer sur Ctrl + C sans terminer le script. Néanmoins, ce choix n'exclut toujours pas correctement la touche de modification Ctrl. (il agit comme si l'utilisateur ne cliquait que sur la touche Ctrl) Référence: Microsoft TechNet - Windows PowerShell Astuce: Appuyez sur n'importe quelle touche pour continuer
Oz Edri
2
Les options 3 et 5 ont un autre inconvénient: ne fonctionne pas sous Linux
bitbonk
43

Je suppose que vous voulez lire l'entrée de la console. Si tel est le cas, utilisez Read-Host.

rediffusion
la source
3
Idem - Peut-être ajouter le texte d'invite volé ci-dessous .. Read-Host -Prompt "Appuyez sur Entrée pour continuer"
Jon H
21

Les solutions comme cmd /c pauseprovoquent le démarrage et l'exécution d'un nouvel interpréteur de commandes en arrière-plan. Bien que acceptable dans certains cas, ce n'est pas vraiment idéal.

Les solutions utilisant Read-Hostforcent l'utilisateur à appuyer Enteret ne sont pas vraiment "n'importe quelle touche".

Cette solution vous donnera une véritable interface "appuyez sur n'importe quelle touche pour continuer" et ne démarrera pas un nouvel interpréteur, qui imitera essentiellement la pausecommande d' origine .

Write-Host "Press any key to continue..."
[void][System.Console]::ReadKey($true)
Ro Yo Mi
la source
Techniquement, ISE est hors de portée parce que la question originale ne posait que sur Powershell 2.0 et exclu ISE. Si vous utilisez ISE, utilisez simplement un point d'arrêt.
Ro Yo Mi
4
1. Je ne suis pas d'accord qu'ISE était hors de portée, mais ce n'est plus pertinent maintenant. 2. Je faisais remarquer que cela ne fonctionne pas dans l'ISE pour aider les passants sur cette question.
Bill_Stewart
2

En plus de la réponse de Michael Sorens :

<6> ReadKey dans un nouveau processus

Start-Process PowerShell {[void][System.Console]::ReadKey($true)} -Wait -NoNewWindow
  • Avantage: accepte toutes les touches mais exclut correctement les touches de modification Maj, Alt, Ctrl.
  • Avantage: fonctionne dans PS-ISE.
le fer
la source
Cela fonctionne très bien, mais une nouvelle fenêtre de PowerShell apparaît, sauf si elle -NoNewWindowa été ajoutée :)
jeuxjeux20
@ jeuxjeux20, merci pour la suggestion, j'ai ajouté ceci à la commande dans la réponse.
iRon