¿Cómo se hace una 'pausa' con PowerShell 2.0?

113

OK, lo estoy perdiendo. PowerShell me está molestando. Me gustaría que apareciera un cuadro de diálogo de pausa, pero no aparecerá.

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
fuente
1
Tuve el mismo problema en PowerShell ISE. Sin embargo, funciona bien en la consola estándar de PowerShell.
Charles Anderson
3
Solo estoy jugando con PowerShell y todavía es muy molesto, ¡incluso 2 1/2 años después!
Bill K
Si lee el enlace de Adam's Tech o el código en la respuesta de @Michael Sorens (aproximadamente a la mitad de la página mientras escribo esto en 2020), puede descubrir una técnica para envolver su pausa if (!$psise) { <# pause #> }. Si eres como yo y el 99% de la razón por la que quieres una pausa es para poder leer la pantalla antes de que parpadee, esto te ayudará, porque si estás en el ISE, no parpadea y no lo haces. 't need the pause
john v kumpf

Respuestas:

88
cmd /c pause | out-null

(No es la forma de PowerShell, pero es mucho más elegante).

Salva árboles. Utilice frases ingeniosas.

Carlos Núñez
fuente
7
/ c Ejecuta el comando especificado por cadena y luego termina | out-null canaliza la salida a out-null, donde nunca lo verá. Si desea ver el mensaje "Presione cualquier tecla para continuar ...", elimine la canalización. Además, esto no parece funcionar en PowerShell ISE. El proceso simplemente se atasca y no puede presionar ninguna tecla. ¿Alguna forma de evitar eso?
Wouter
1
@Wouter Vea esta publicación de blog: Cómo pausar correctamente un script de PowerShell
Nick
7
@Nick sí, 47 líneas de código para reemplazar "cmd / c pause | out-null", que suena a la forma de PowerShell.
Bill K
@BillK La publicación a la que vinculé responde la pregunta de Wouter. ¿No estás de acuerdo?
Nick
6
No fue un comentario sobre tu respuesta, creo que tienes toda la razón. Es un comentario sobre PowerShell. Estoy moderadamente disgustado: no he visto tanta verbosidad oscurecedora sin sentido desde que programé en Cobol.
Bill K
234

Creo que vale la pena recapitular / resumir las opciones aquí para mayor claridad ... luego ofrecer una nueva variación que creo que proporciona la mejor utilidad.

<1> ReadKey (System.Console)

write-host "Press any key to continue..."
[void][System.Console]::ReadKey($true)
  • Ventaja: Acepta cualquier tecla pero excluye correctamente las teclas modificadoras Shift, Alt, Ctrl.
  • Desventaja: no funciona en PS-ISE.

<2> ReadKey (RawUI)

Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
  • Desventaja: no funciona en PS-ISE.
  • Desventaja: no excluye las teclas modificadoras.

<3> cmd

cmd /c Pause | Out-Null
  • Desventaja: no funciona en PS-ISE.
  • Desventaja: Lanza visiblemente un nuevo shell / ventana en el primer uso; no se nota en el uso posterior pero todavía tiene la sobrecarga

<4> Host de lectura

Read-Host -Prompt "Press Enter to continue"
  • Ventaja: Funciona en PS-ISE.
  • Desventaja: solo acepta la tecla Intro.

<5> Compuesto ReadKey

Esta es una combinación de <1> anterior con la solución ISE / kludge extraída de la propuesta en el blog tecnológico de Adam (cortesía de Nick de comentarios anteriores en esta página). Hice dos ligeras mejoras en este último: agregué Test-Path para evitar un error si usa Set-StrictMode (lo hace, ¿no?) Y el Write-Host final para agregar una nueva línea después de presionar la tecla para poner el mensaje en el lugar correcto.

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
    }
}
  • Ventaja: Acepta cualquier tecla pero excluye correctamente las teclas modificadoras Shift, Alt, Ctrl.
  • Ventaja: funciona en PS-ISE (aunque solo con Enter o clic del mouse)
  • Desventaja: ¡No es de una sola línea!
Michael Sorens
fuente
9
La mejor respuesta, especialmente porque proporciona una solución que funciona en todas partes
Petr
¡Gran respuesta! Me gustaría señalar que agregar el AllowCtrlCparámetro a la opción 2 permite al usuario hacer clic en Ctrl + C sin terminar el script. Sin embargo, esta opción todavía no excluye correctamente la tecla modificadora Ctrl. (actúa como si el usuario solo hiciera clic en la tecla Ctrl) Referencia: Microsoft TechNet - Windows PowerShell Consejo: presione cualquier tecla para continuar
Oz Edri
2
Las opciones 3 y 5 tienen otra desventaja: no funciona en linux
bitbonk
43

Supongo que desea leer la entrada de la consola. Si es así, utilice Read-Host.

repetición
fuente
3
Ditto - Quizás agregue el texto de aviso robado desde abajo .. Read-Host -Prompt "Presione Enter para continuar"
Jon H
21

Las soluciones como cmd /c pausehacen que un nuevo intérprete de comandos se inicie y se ejecute en segundo plano. Aunque es aceptable en algunos casos, esto no es realmente ideal.

Las soluciones que utilizan Read-Hostobligan al usuario a presionar Entery no son realmente "ninguna tecla".

Esta solución le dará una verdadera interfaz de "presione cualquier tecla para continuar" y no iniciará un nuevo intérprete, que esencialmente imitará el pausecomando original .

Write-Host "Press any key to continue..."
[void][System.Console]::ReadKey($true)
Ro Yo Mi
fuente
Técnicamente, ISE está fuera de alcance porque la pregunta original solo se refería a Powershell 2.0 y excluía ISE. Si está utilizando ISE, utilice un punto de interrupción.
Ro Yo Mi
4
1. No estoy de acuerdo con que ISE esté fuera de alcance, pero eso es irrelevante ahora. 2. Estaba notando que no funciona en el ISE ayudar a los transeúntes en esta pregunta.
Bill_Stewart
2

Además de la respuesta de Michael Sorens :

<6> ReadKey en un nuevo proceso

Start-Process PowerShell {[void][System.Console]::ReadKey($true)} -Wait -NoNewWindow
  • Ventaja: Acepta cualquier tecla pero excluye correctamente las teclas modificadoras Shift, Alt, Ctrl.
  • Ventaja: Funciona en PS-ISE.
hierro
fuente
Esto funciona muy bien, pero abre una nueva ventana de powershell, a menos que -NoNewWindowse haya agregado :)
jeuxjeux20
@ jeuxjeux20, gracias por la sugerencia, agregué esto al comando en la respuesta.
iRon