Wie macht man mit PowerShell 2.0 eine Pause?

113

OK, ich verliere es. PowerShell nervt mich. Ich möchte, dass ein Pausendialog angezeigt wird, der jedoch nicht angezeigt wird.

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
quelle
1
Ich hatte das gleiche Problem in PowerShell ISE. Funktioniert jedoch gut in der Standard-PowerShell-Konsole.
Charles Anderson
3
Ich spiele nur mit Powershell und es ist immer noch verdammt nervig, sogar 2 1/2 Jahre später!
Bill K
Wenn Sie den Adam's Tech-Link oder den Code in der Antwort von @Michael Sorens lesen (ungefähr in der Mitte der Seite, als ich dies im Jahr 2020 schreibe), können Sie eine Technik entdecken, mit der Sie Ihre Pause einpacken können if (!$psise) { <# pause #> }. Wenn Sie wie ich sind und zu 99% eine Pause wünschen, damit Sie den Bildschirm lesen können, bevor er wegblinkt, hilft dies, denn wenn Sie sich in der ISE befinden, blinkt er nicht weg und Sie ziehen nicht an Ich brauche keine Pause
John v Kumpf

Antworten:

88
cmd /c pause | out-null

(Es ist nicht die PowerShell-Methode, aber es ist viel eleganter.)

Rette Bäume. Verwenden Sie Einzeiler.

Carlos Nunez
quelle
7
/ c Führt den durch string angegebenen Befehl aus und beendet dann | out-null leitet die Ausgabe an out-null weiter, wo Sie sie nie sehen werden. Wenn Sie die Meldung "Drücken Sie eine beliebige Taste, um fortzufahren ..." sehen möchten, entfernen Sie die Pipe. Dies scheint auch in PowerShell ISE nicht zu funktionieren. Der Prozess bleibt einfach hängen und Sie können keine Taste drücken. Irgendwie um das herum?
Wouter
1
@Wouter Siehe diesen Blog-Beitrag: Wie man ein PowerShell-Skript richtig
Nick
7
@Nick ja, 47 Codezeilen als Ersatz für "cmd / c pause | out-null", das klingt nach PowerShell.
Bill K
@ BillK Der Beitrag, den ich verlinkt habe, beantwortet Wouters Frage. Stimmen Sie nicht zu?
Nick
6
Es war kein Kommentar zu Ihrer Antwort, ich denke, Sie haben vollkommen recht. Es ist ein Kommentar zu PowerShell. Ich bin mäßig angewidert - ich habe seit meiner Programmierung in Cobol nicht mehr so ​​viel sinnlose undurchsichtige Ausführlichkeit gesehen.
Bill K
234

Ich denke, es lohnt sich, die Auswahl hier aus Gründen der Klarheit zusammenzufassen / zusammenzufassen ... und dann eine neue Variante anzubieten, von der ich glaube, dass sie den besten Nutzen bietet.

<1> ReadKey (System.Console)

write-host "Press any key to continue..."
[void][System.Console]::ReadKey($true)
  • Vorteil: Akzeptiert alle Tasten, schließt jedoch die Modifikatortasten Umschalt, Alt und Strg ordnungsgemäß aus.
  • Nachteil: Funktioniert nicht in PS-ISE.

<2> ReadKey (RawUI)

Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
  • Nachteil: Funktioniert nicht in PS-ISE.
  • Nachteil: Modifikatortasten werden nicht ausgeschlossen.

<3> cmd

cmd /c Pause | Out-Null
  • Nachteil: Funktioniert nicht in PS-ISE.
  • Nachteil: Startet sichtbar neue Shell / Fenster bei der ersten Verwendung; bei späterer Verwendung nicht erkennbar, hat aber immer noch den Overhead

<4> Read-Host

Read-Host -Prompt "Press Enter to continue"
  • Vorteil: Funktioniert in PS-ISE.
  • Nachteil: Akzeptiert nur die Eingabetaste.

<5> ReadKey-Verbund

Dies ist eine Zusammenstellung von <1> oben mit der ISE-Problemumgehung / Kludge, die aus dem Vorschlag in Adams Tech-Blog extrahiert wurde (mit freundlicher Genehmigung von Nick aus früheren Kommentaren auf dieser Seite). Ich habe zwei kleinere Verbesserungen an letzterem vorgenommen: Test-Path hinzugefügt, um einen Fehler zu vermeiden, wenn Sie Set-StrictMode verwenden (Sie tun es, nicht wahr?! ) Und den letzten Write-Host, um nach Ihrem Tastendruck eine neue Zeile hinzuzufügen, um das zu setzen Eingabeaufforderung an der richtigen Stelle.

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
    }
}
  • Vorteil: Akzeptiert alle Tasten, schließt jedoch die Modifikatortasten Umschalt, Alt und Strg ordnungsgemäß aus.
  • Vorteil: Funktioniert in PS-ISE (allerdings nur mit Enter oder Mausklick)
  • Nachteil: Kein Einzeiler!
Michael Sorens
quelle
9
Beste Antwort, vor allem, weil es eine Lösung bietet, die überall funktioniert
Petr
Gute Antwort! Ich möchte darauf hinweisen, dass AllowCtrlCder Benutzer durch Hinzufügen des Parameters zu Auswahl 2 auf Strg + C klicken kann, ohne das Skript zu beenden. Trotzdem schließt diese Auswahl die Modifikationstaste Strg noch nicht richtig aus. (Es verhält sich so, als ob der Benutzer nur auf die Strg-Taste klickt.) Referenz: Microsoft TechNet - Windows PowerShell Tipp: Drücken Sie eine beliebige Taste, um fortzufahren
Oz Edri
2
Option 3 und 5 haben einen weiteren Nachteil: funktioniert nicht unter Linux
Bitbonk
43

Ich gehe davon aus, dass Sie Eingaben von der Konsole lesen möchten. Wenn ja, verwenden Sie Read-Host.

Wiederholung
quelle
3
Ditto - Fügen Sie möglicherweise den von unten gestohlenen Aufforderungstext hinzu. Read-Host -Prompt "Drücken Sie die Eingabetaste, um fortzufahren"
Jon H
21

Die Lösungen wie cmd /c pausebewirken, dass ein neuer Befehlsinterpreter im Hintergrund gestartet und ausgeführt wird. Obwohl dies in einigen Fällen akzeptabel ist, ist dies nicht wirklich ideal.

Die verwendeten Lösungen Read-Hostzwingen den Benutzer zum Drücken Enterund sind nicht wirklich "irgendeine Taste".

Diese Lösung gibt Ihnen eine echte "Drücken Sie eine beliebige Taste, um fortzufahren" -Schnittstelle und startet keinen neuen Interpreter, der im Wesentlichen den ursprünglichen pauseBefehl nachahmt.

Write-Host "Press any key to continue..."
[void][System.Console]::ReadKey($true)
Ro Yo Mi.
quelle
Technisch gesehen ist ISE nicht möglich, da die ursprüngliche Frage nur zu Powershell 2.0 gestellt und ISE ausgeschlossen wurde. Wenn Sie ISE verwenden, verwenden Sie einfach einen Haltepunkt.
Ro Yo Mi
4
1. Ich bin nicht der Meinung, dass ISE außerhalb des Anwendungsbereichs lag, aber das ist jetzt irrelevant. 2. Ich habe festgestellt, dass es in der ISE nicht funktioniert, Passanten bei dieser Frage zu unterstützen.
Bill_Stewart
2

Neben der Antwort von Michael Sorens :

<6> ReadKey in einem neuen Prozess

Start-Process PowerShell {[void][System.Console]::ReadKey($true)} -Wait -NoNewWindow
  • Vorteil: Akzeptiert alle Tasten, schließt jedoch die Modifikatortasten Umschalt, Alt und Strg ordnungsgemäß aus.
  • Vorteil: Funktioniert in PS-ISE.
Eisen
quelle
Dies funktioniert großartig, öffnet aber ein neues Fenster mit Powershell, sofern -NoNewWindowes nicht hinzugefügt wurde :)
jeuxjeux20
@ jeuxjeux20, danke für den Vorschlag, ich habe diesen Befehl in der Antwort hinzugefügt.
iRon