Jak zrobić „pauzę” w PowerShell 2.0?

114

OK, tracę to. PowerShell mnie denerwuje. Chciałbym, aby pojawiło się okno dialogowe wstrzymania, ale się nie pojawi.

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
źródło
1
Miałem ten sam problem w PowerShell ISE. Działa jednak dobrze w standardowej konsoli PowerShell.
Charles Anderson
3
Po prostu bawię się PowerShell i wciąż jest to irytujące, nawet 2 1/2 roku później!
Bill K
Jeśli przeczytasz link Adam's Tech lub kod w odpowiedzi @Michael Sorens (mniej więcej w połowie strony, kiedy piszę to w 2020 roku), możesz odkryć technikę zawijania swojej pauzy if (!$psise) { <# pause #> }. Jeśli jesteś podobny do mnie i 99% powodu, dla którego chcesz pauzować, jest po to, abyś mógł przeczytać ekran, zanim zamrugnie, to pomoże, ponieważ jeśli jesteś w ISE, to nie mrugnie, a ty nie Nie potrzebuję przerwy
john v kumpf

Odpowiedzi:

89
cmd /c pause | out-null

(To nie jest sposób PowerShell, ale jest o wiele bardziej elegancki).

Ratuj drzewa. Użyj jednowierszowych.

Carlos Nunez
źródło
7
/ c Wykonuje polecenie określone przez łańcuch, a następnie kończy | out-null potokuje wyjście do out-null, gdzie nigdy go nie zobaczysz. Jeśli chcesz zobaczyć komunikat „Naciśnij dowolny klawisz, aby kontynuować…”, usuń potok. Ponadto wydaje się, że to nie działa w PowerShell ISE. Proces po prostu utknął i nie możesz nacisnąć żadnego klawisza. Jakoś to obejść?
Wouter
1
@Wouter Zobacz ten wpis na blogu: Jak prawidłowo wstrzymać skrypt PowerShell
Nick,
7
@Nick tak, 47 linii kodu zastępujących "cmd / c pause | out-null", to brzmi jak sposób PowerShell.
Bill K
@BillK Post, do którego utworzyłem łącze, odpowiada na pytanie Woutera. Czy się nie zgadzasz?
Nick
6
To nie był komentarz do twojej odpowiedzi, myślę, że masz całkowitą rację. To komentarz do PowerShell. Jestem umiarkowanie zniesmaczony - od czasu programowania w Cobolu nie widziałem takiej bezsensownej, zaciemniającej szczegółowości.
Bill K
234

Myślę, że dla jasności warto podsumować / podsumować wybory tutaj ... a następnie zaproponować nową odmianę, która moim zdaniem zapewnia najlepszą użyteczność.

<1> ReadKey (Konsola systemowa)

write-host "Press any key to continue..."
[void][System.Console]::ReadKey($true)
  • Zaleta: akceptuje dowolny klawisz, ale prawidłowo wyklucza klawisze modyfikujące Shift, Alt, Ctrl.
  • Wada: nie działa w PS-ISE.

<2> ReadKey (RawUI)

Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
  • Wada: nie działa w PS-ISE.
  • Wada: nie wyklucza klawiszy modyfikujących.

<3> cmd

cmd /c Pause | Out-Null
  • Wada: nie działa w PS-ISE.
  • Wada: Widocznie uruchamia nową powłokę / okno przy pierwszym użyciu; nie zauważalny przy kolejnym użyciu, ale nadal ma narzut

<4> Read-Host

Read-Host -Prompt "Press Enter to continue"
  • Zaleta: działa w PS-ISE.
  • Wada: akceptuje tylko klawisz Enter.

<5> Kompozyt ReadKey

To jest połączenie <1> powyżej z obejściem / kludge ISE wyodrębnionym z propozycji na blogu technicznym Adama (dzięki uprzejmości Nicka z wcześniejszych komentarzy na tej stronie). Dokonałem dwóch drobnych ulepszeń w tym drugim: dodałem Test-Path, aby uniknąć błędu, jeśli używasz Set-StrictMode (robisz, prawda ?!) i ostatni Write-Host, aby dodać nową linię po naciśnięciu klawisza, aby umieścić podpowiedź we właściwym miejscu.

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
    }
}
  • Zaleta: akceptuje dowolny klawisz, ale prawidłowo wyklucza klawisze modyfikujące Shift, Alt, Ctrl.
  • Zaleta: działa w PS-ISE (choć tylko z Enter lub kliknięciem myszy)
  • Wada: nie jest to jedna linijka!
Michael Sorens
źródło
9
Najlepsza odpowiedź, zwłaszcza, że ​​zapewnia rozwiązanie, które działa wszędzie
Petr
Świetna odpowiedź! Chciałbym zauważyć, że dodanie AllowCtrlCparametru do wyboru 2 umożliwia użytkownikowi kliknięcie Ctrl + C bez kończenia skryptu. Niemniej jednak ten wybór nadal nie wyklucza poprawnie klawisza modyfikującego Ctrl. (zachowuje się tak, jakby użytkownik kliknął tylko klawisz Ctrl) Odniesienie: Microsoft TechNet - Windows PowerShell Wskazówka: naciśnij dowolny klawisz, aby kontynuować
Oz Edri
2
Opcje 3 i 5 mają jeszcze jedną wadę: nie działa na Linuksie
bitbonk
43

Zakładam, że chcesz czytać dane wejściowe z konsoli. Jeśli tak, użyj Read-Host.

ponownie odtwarzać
źródło
3
Jak wyżej - Może dodać tekst zachęty ukradziony z dołu .. Read-Host -Prompt "Naciśnij Enter, aby kontynuować"
Jon H
21

Rozwiązania takie jak cmd /c pause powodują, że nowy interpreter poleceń uruchamia się i działa w tle. Chociaż w niektórych przypadkach jest to dopuszczalne, nie jest to idealne rozwiązanie.

Rozwiązania wykorzystujące Read-Hostzmuszają użytkownika do naciśnięciaEnter i tak naprawdę nie są „żadnym klawiszem”.

To rozwiązanie da ci prawdziwy interfejs „naciśnij dowolny klawisz, aby kontynuować” i nie uruchomi nowego interpretera, który zasadniczo będzie naśladował oryginalne pausepolecenie.

Write-Host "Press any key to continue..."
[void][System.Console]::ReadKey($true)
Ro Yo Mi
źródło
Technicznie ISE jest poza zakresem, ponieważ pierwotne pytanie dotyczyło tylko Powershell 2.0 i wykluczało ISE. Jeśli używasz ISE, po prostu użyj punktu przerwania.
Ro Yo Mi
4
1. Nie zgadzam się, że ISE było poza zakresem, ale teraz to nie ma znaczenia. 2. Zauważyłem, że w ISE nie działa pomoc przechodniom w tej kwestii.
Bill_Stewart,
2

Oprócz odpowiedzi Michaela Sorensa :

<6> ReadKey w nowym procesie

Start-Process PowerShell {[void][System.Console]::ReadKey($true)} -Wait -NoNewWindow
  • Zaleta: akceptuje dowolny klawisz, ale prawidłowo wyklucza klawisze modyfikujące Shift, Alt, Ctrl.
  • Zaleta: działa w PS-ISE.
żelazo
źródło
Działa świetnie, ale wyskakuje nowe okno programu PowerShell, chyba -NoNewWindowże zostało dodane :)
jeuxjeux20
@ jeuxjeux20, dzięki za sugestię, dodałem to do polecenia w odpowiedzi.
iRon