如何使用 PowerShell 2.0实现“暂停”?

好吧,我快不行了。 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
241872 次浏览

我假设您希望从控制台读取输入。

cmd /c pause | out-null

(这不是 PowerShell 的风格,但是更加优雅。)

保护树木,使用俏皮话。

cmd /c pause这样的解决方案导致一个新的命令解释器在后台启动和运行。虽然在某些情况下可以接受,但这并不是真正理想的。

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

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

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

我认为为了清晰起见,我们有必要在这里概括/总结一下这些选择... 然后提供一种我认为能够提供最佳实用性的新变体。

< 1 > ReadKey (System. Console)

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 /c Pause | Out-Null
  • 缺点: 不能在 PS-ISE 中工作。
  • 缺点: 在第一次使用时可以启动新的 shell/窗口; 在后续使用时不明显,但仍然有开销

< 4 > 读取主机

Read-Host -Prompt "Press Enter to continue"
  • 优势: 适用于 PS-ISE。
  • 缺点: 只接受输入键。

< 5 > ReadKey 复合

这是上面的 < 1 > 与从 亚当的科技博客提案中提取的 ISE 解决方案/组件的组合(由 Nick 在本页的早期评论中提供)。对于后者,我做了两个小小的改进: 添加了 Test-Path,以避免在使用 Set-StrictMode时出现错误(您确实使用了,不是吗? !)以及最后一个 Write-Host,在按键之后添加一个换行符,以便将提示符放在正确的位置。

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 (尽管只能通过回车或鼠标单击)
  • 缺点: 不是一句俏皮话!

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

< 6 > 新进程中的 ReadKey

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

在使用 ReadKey之前,您可能希望使用 FlushInputBuffer丢弃任何错误输入到控制台中的字符,特别是对于长时间运行的操作:

Write-Host -NoNewLine 'Press any key to continue...'
$Host.UI.RawUI.FlushInputBuffer()
$Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown') | Out-Null

10年后我来到这里... ... 不知道从什么时候开始,但是“暂停”在 PowerShell 中和在 DOS 命令行中一样有效。

如果你想在按键上添加一个计时器,这在 PS 5.1中可以实现:

 $i=1
while (
!([Console]::KeyAvailable) -and
($i -le 10)
) {
sleep 1
Write-Host “$i..” -NoNewLine
$i++
}

请注意,c # $Host.UI.RawUI 的键可用方法目前在 PS 2或3之后的许多 PS 版本中都有漏洞。

选项 < 5 > 中 PS-ISE 的一行程序:

[Void][Windows.Forms.MessageBox]::Show("Click OK to continue.", "Script Paused")