如何使用PowerShell 2.0进行“暂停”?


113

好,我丢了。PowerShell让我很烦。我希望显示一个暂停对话框,但不会。

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

1
我在PowerShell ISE中遇到了同样的问题。虽然可以在标准PowerShell控制台中正常工作。
Charles Anderson

3
我只是搞砸了powershell,即使在2 1/2年后,它仍然令人讨厌。
Bill K

如果您阅读了Adam的Tech链接@Michael Sorens答案中的代码(大约是我在2020年写此页面的一半),您可能会发现一种将暂停包裹在中的技术if (!$psise) { <# pause #> }。如果您像我一样,并且希望暂停的原因有99%是为了让您可以在屏幕闪烁之前阅读屏幕,那么这将有所帮助,因为如果您在ISE中,它不会闪烁并且您不知道不需要暂停
约翰v昆普夫

Answers:


88
cmd /c pause | out-null

(这不是PowerShell的方式,但是它要优雅得多。)

保存树木。使用单线。


7
/ c执行由字符串指定的命令,然后终止| out-null将输出管道输出到out-null,您将永远看不到它。如果您想看到“按任意键继续...”消息,请删除管道。此外,这似乎在PowerShell ISE中不起作用。该过程只是卡住了,您不能按任何键。可以解决吗?
Wouter 2012年

1
@Wouter参阅此博客文章:如何正确暂停PowerShell脚本
Nick

7
@Nick是的,47行代码来替换“ cmd / c pause | out-null”,这听起来像PowerShell方式。
Bill K

@BillK我链接到的帖子回答了Wouter的问题。你不同意吗?
尼克

6
这不是对您的回答的评论,我认为您是完全正确的。这是关于PowerShell的评论。我有点恶心-自从我在Cobol中编程以来,我从未见过如此毫无意义的冗长冗长。
Bill K

234

我认为有必要对这里的选择进行总结/总结以使其更加清晰...然后提供一个新的变体,我相信它可以提供最佳的实用性。

<1> ReadKey(系统控制台)

write-host "Press any key to continue..."
[void][System.Console]::ReadKey($true)
  • 优点:可以接受任何键,但可以正确排除Shift,Alt和Ctrl修饰键。
  • 缺点:在PS-ISE中不起作用。

<2> ReadKey(RawUI)

Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
  • 缺点:在PS-ISE中不起作用。
  • 缺点:不排除修饰键。

<3> cmd

cmd /c Pause | Out-Null
  • 缺点:在PS-ISE中不起作用。
  • 缺点:首次使用时会启动新的外壳/窗口;后续使用不明显,但仍有开销

<4>读主机

Read-Host -Prompt "Press Enter to continue"
  • 优点:可在PS-ISE中使用。
  • 缺点:仅接受Enter键。

<5> ReadKey复合

这是上面<1>的综合内容,其中包括ISE解决方法/污点(摘自Adam's Tech Blog上的建议)(由Nick 友情提供,此页的早期评论)。我对后者做了两个小改进:添加了Test-Path以避免在使用Set-StrictMode时出错(您愿意,不是吗?在正确的位置提示。

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
    }
}
  • 优点:可以接受任何键,但可以正确排除Shift,Alt和Ctrl修饰键。
  • 优点:可在PS-ISE中使用(尽管只能通过Enter或单击鼠标)
  • 缺点:不是单线的!

9
最佳答案,尤其是因为它提供了可在任何地方使用的解决方案
Petr 2014年

好答案!我想指出的是,将AllowCtrlC参数添加到选项2允许用户单击Ctrl + C,而无需终止脚本。但是,此选择仍不能正确排除Ctrl修饰键。(它的作用就像用户仅单击Ctrl键一样)参考:Microsoft TechNet-Windows PowerShell提示:按任意键继续
Oz Edri

2
选项3和5还有另一个缺点:在Linux上不起作用
bitbonk

43

我假设您想从控制台读取输入。如果是这样,请使用Read-Host


3
同上-也许添加从下面窃取的提示文本。读主机-提示“按Enter继续”
Jon H

21

诸如此类的解决方案cmd /c pause使新的命令解释器在后台启动并运行。尽管在某些情况下可以接受,但这并不是很理想。

使用该解决方案会Read-Host迫使用户按下Enter,而并不是真正的“任何键”。

该解决方案将为您提供真正的“按任意键继续”界面,并且不会启动新的解释器,该解释器实际上将模仿原始pause命令。

Write-Host "Press any key to continue..."
[void][System.Console]::ReadKey($true)

从技术上讲,ISE不在范围之内,因为原始问题仅询问有关Powershell 2.0的信息,而排除了ISE。如果您使用的是ISE,则只需使用断点即可。
Ro Yo Mi

4
1.我不同意ISE不在范围之内,但是现在已经无关紧要了。2.我注意到在ISE中无法协助过路人解决此问题。
Bill_Stewart '17

2

除了迈克尔·索伦斯的答案:

<6>在新过程中使用ReadKey

Start-Process PowerShell {[void][System.Console]::ReadKey($true)} -Wait -NoNewWindow
  • 优点:可以接受任何键,但可以正确排除Shift,Alt和Ctrl修饰键。
  • 优点:可在PS-ISE中使用。

这很好用,但是会弹出一个新的-NoNewWindow
Powershell

@ jeuxjeux20,感谢您的建议,我已将此添加到命令中的答案中。
iRon
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.