Como você faz uma 'Pausa' com o PowerShell 2.0?

113

OK, estou perdendo o controle. PowerShell está me incomodando. Eu gostaria que uma caixa de diálogo de pausa aparecesse, mas não vai.

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
fonte
1
Eu tive o mesmo problema no PowerShell ISE. Funciona bem no console padrão do PowerShell.
Charles Anderson
3
Estou apenas brincando com o PowerShell e ainda é chato pra caralho, mesmo 2 anos e meio depois!
Bill K de
Se você ler o link Adam's Tech ou o código na resposta de @Michael Sorens (mais ou menos na metade da página enquanto eu escrevo isso em 2020), você pode descobrir uma técnica para encerrar sua pausa if (!$psise) { <# pause #> }. Se você é como eu e 99% do motivo pelo qual você quer uma pausa é para poder ler a tela antes que ela pisque, isso vai ajudar, porque se você estiver no ISE, ela não piscará e você não não preciso de uma pausa
john v kumpf

Respostas:

88
cmd /c pause | out-null

(Não é a maneira do PowerShell, mas é muito mais elegante.)

Salve as árvores. Use one-liners.

Carlos Nunez
fonte
7
/ c Executa o comando especificado por string e, em seguida, termina | out-null canaliza a saída para out-null, onde você nunca a verá Se quiser ver a mensagem "Pressione qualquer tecla para continuar ...", remova o cano. Além disso, isso não parece funcionar no PowerShell ISE. O processo simplesmente fica travado e você não consegue pressionar nenhuma tecla. Alguma maneira de contornar isso?
Wouter
1
@Wouter Veja esta postagem do blog: Como pausar corretamente um script do PowerShell
Nick
7
@Nick sim, 47 linhas de código para substituir "cmd / c pause | out-null", isso soa como o jeito do PowerShell.
Bill K de
@BillK O post que vinculei responde à pergunta de Wouter. Você discorda?
Nick
6
Não foi um comentário sobre a sua resposta, acho que você tem toda razão. É um comentário sobre PowerShell. Estou moderadamente enojado - não vi essa verbosidade obscurecedora e inútil desde que programei em Cobol.
Bill K de
234

Acho que vale a pena recapitular / resumir as opções aqui para maior clareza ... e então oferecer uma nova variação que acredito fornecer a melhor utilidade.

<1> ReadKey (System.Console)

write-host "Press any key to continue..."
[void][System.Console]::ReadKey($true)
  • Vantagem: aceita qualquer tecla, mas exclui adequadamente as teclas modificadoras Shift, Alt, Ctrl.
  • Desvantagem: Não funciona no PS-ISE.

<2> ReadKey (RawUI)

Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
  • Desvantagem: Não funciona no PS-ISE.
  • Desvantagem: Não exclui teclas modificadoras.

<3> cmd

cmd /c Pause | Out-Null
  • Desvantagem: Não funciona no PS-ISE.
  • Desvantagem: Visivelmente abre um novo shell / janela na primeira utilização; não perceptível no uso subsequente, mas ainda tem a sobrecarga

<4> Read-Host

Read-Host -Prompt "Press Enter to continue"
  • Vantagem: Funciona em PS-ISE.
  • Desvantagem: Aceita apenas a tecla Enter.

<5> Composto ReadKey

Este é um composto de <1> acima com a solução alternativa / kludge do ISE extraída da proposta no Blog de Tecnologia de Adam (cortesia de Nick em comentários anteriores nesta página). Fiz duas pequenas melhorias no último: adicionei Test-Path para evitar um erro se você usar Set-StrictMode (você usa , não é ?!) e o Write-Host final para adicionar uma nova linha após seu pressionamento de tecla para colocar o prompt no lugar certo.

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
    }
}
  • Vantagem: aceita qualquer tecla, mas exclui adequadamente as teclas modificadoras Shift, Alt, Ctrl.
  • Vantagem: Funciona em PS-ISE (embora apenas com Enter ou clique do mouse)
  • Desvantagem: Não é uma linha única!
Michael Sorens
fonte
9
Melhor resposta, especialmente porque fornece uma solução que funciona em qualquer lugar
Petr
Ótima resposta! Gostaria de observar que adicionar o AllowCtrlCparâmetro à opção 2 permite que o usuário clique em Ctrl + C sem encerrar o script. No entanto, essa escolha ainda não exclui adequadamente a tecla modificadora Ctrl. (age como se o usuário clicasse apenas na tecla Ctrl) Referência: Microsoft TechNet - Windows PowerShell Dica: pressione qualquer tecla para continuar
Oz Edri
2
As opções 3 e 5 têm outra desvantagem: não funciona no linux
bitbonk
43

Presumo que você deseja ler a entrada do console. Se sim, use Read-Host.

repetir
fonte
3
Idem - Talvez adicione o texto do prompt roubado de baixo. Read-Host -Prompt "Pressione Enter para continuar"
Jon H
21

As soluções cmd /c pausefazem com que um novo interpretador de comandos seja iniciado e executado em segundo plano. Embora seja aceitável em alguns casos, isso não é realmente ideal.

As soluções que usam Read-Hostforçam o usuário a pressionar Entere não são realmente "nenhuma tecla".

Esta solução fornecerá uma interface verdadeira de "pressione qualquer tecla para continuar" e não iniciará um novo interpretador, que essencialmente imitará o pausecomando original .

Write-Host "Press any key to continue..."
[void][System.Console]::ReadKey($true)
Ro Yo Mi
fonte
Tecnicamente, o ISE está fora do escopo porque a pergunta original feita apenas sobre o Powershell 2.0 e excluiu o ISE. Se você estiver usando o ISE, basta usar um ponto de interrupção.
Ro Yo Mi
4
1. Não concordo que o ISE estava fora do escopo, mas isso é irrelevante agora. 2. Eu estava observando que não funciona no ISE para ajudar os transeuntes nessa questão.
Bill_Stewart
2

Além da resposta de Michael Sorens :

<6> ReadKey em um novo processo

Start-Process PowerShell {[void][System.Console]::ReadKey($true)} -Wait -NoNewWindow
  • Vantagem: aceita qualquer tecla, mas exclui adequadamente as teclas modificadoras Shift, Alt, Ctrl.
  • Vantagem: Funciona em PS-ISE.
ferro
fonte
Isso funciona muito bem, mas abre uma nova janela do PowerShell, a menos que -NoNewWindowtenha sido adicionado :)
jeuxjeux20
@ jeuxjeux20, obrigado pela sugestão, adicionei este comando na resposta.
iRon