Как сделать паузу в PowerShell 2.0?

114

Хорошо, я теряю это. 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.
Чарльз Андерсон
3
Я просто возился с PowerShell, и это до сих пор чертовски раздражает, даже спустя два с половиной года!
Bill K
Если вы прочитаете ссылку на Adam's Tech или код в ответе @Michael Sorens (примерно на полпути вниз по странице, когда я пишу это в 2020 году), вы можете обнаружить технику обертывания паузы if (!$psise) { <# pause #> }. Если вы похожи на меня и на 99% вам нужна пауза, чтобы вы могли прочитать экран до того, как он мигнет, это поможет, потому что если вы находитесь в ISE, он не мигает, и вы не мигаете. Пауза не нужна
Джон в Кампф

Ответы:

89
cmd /c pause | out-null

(Это не способ PowerShell, но он намного элегантнее.)

Спасайте деревья. Используйте однострочники.

Карлос Нуньес
источник
7
/ c Выполняет команду, указанную в строке, а затем завершает | out-null направляет вывод в out-null, где вы его никогда не увидите. Если вы хотите увидеть сообщение «Нажмите любую клавишу для продолжения ...», удалите конвейер. Кроме того, похоже, что это не работает в PowerShell ISE. Процесс просто зависает, и вы не можете нажать ни одну клавишу. Как обойти это?
Wouter
1
@Wouter См. Это сообщение в блоге: Как правильно
Ник,
7
@Nick да, 47 строк кода для замены "cmd / c pause | out-null", которые звучат как способ PowerShell.
Bill K
@BillK Сообщение, на которое я указал, отвечает на вопрос Воутера. Вы не согласны?
Ник
6
Это не было комментарием к вашему ответу, я думаю, вы совершенно правы. Это комментарий к PowerShell. Мне умеренно противно - я не видел такого бессмысленного затемняющего многословия с тех пор, как программировал на Коболе.
Bill K
234

Я думаю, что для ясности стоит повторить / резюмировать варианты выбора ... а затем предложить новый вариант, который, как я считаю, обеспечивает лучшую полезность.

<1> ReadKey (System.Console)

write-host "Press any key to continue..."
[void][System.Console]::ReadKey($true)
  • Преимущество: принимает любую клавишу, но правильно исключает клавиши-модификаторы Shift, Alt, Ctrl.
  • Недостаток: не работает в PS-ISE.

<2> Ключ чтения (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 (любезно предоставлено Ником из предыдущих комментариев на этой странице). Я внес два небольших улучшения в последнее: добавил 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 (правда, только с Enter или щелчком мыши)
  • Недостаток: не однострочный!
Майкл Соренс
источник
9
Лучший ответ, особенно потому, что он предлагает решение, которое работает везде
Петр
Отличный ответ! Я хотел бы отметить, что добавление AllowCtrlCпараметра к варианту 2 позволяет пользователю нажать Ctrl + C, не прерывая скрипт. Тем не менее, этот выбор по-прежнему должным образом не исключает клавишу-модификатор Ctrl. (действует так же, как если бы пользователь нажимал только клавишу Ctrl) Ссылка: Microsoft TechNet - Совет Windows PowerShell: нажмите любую клавишу, чтобы продолжить
Оз Эдри
2
У вариантов 3 и 5 есть еще один недостаток: не работает на linux
bitbonk
43

Я предполагаю, что вы хотите читать ввод с консоли. Если да, используйте Read-Host.

повторный показ
источник
3
То же самое - Может быть, добавить текст подсказки, украденный снизу .. Read-Host - Подсказка «Нажмите Enter, чтобы продолжить»
Джон Х
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, просто используйте точку останова.
Ро Йо Ми
4
1. Я не согласен, что ISE выходила за рамки, но сейчас это не имеет значения. 2. Я заметил, что в ISE не работает помогать прохожим по этому вопросу.
Bill_Stewart
2

В дополнение к ответу Майкла Соренса :

<6> ReadKey в новом процессе

Start-Process PowerShell {[void][System.Console]::ReadKey($true)} -Wait -NoNewWindow
  • Преимущество: принимает любую клавишу, но правильно исключает клавиши-модификаторы Shift, Alt, Ctrl.
  • Преимущество: Работает в PS-ISE.
железо
источник
Это отлично работает, но выскакивает новое окно PowerShell, если -NoNewWindowне было добавлено :)
jeuxjeux20
@ jeuxjeux20, спасибо за предложение, я добавил это в команду в ответе.
iRon