We rise up for the things we believe in over and over again

Пользовательский ввод. Обычно его ожидание программируется без особых проблем - ставишь read-host где нужно с нужными параметрами, и дело почти всегда с концом. А сегодня задачка попалась более заковыристая. Скрипт должен ждать Х секунд, после чего запуститься заново, НО! Если в течение этих Х секунд нажата любая кнопка - скрипт должен перезапуститься сразу же. Как решать?
Быстрый гуглеж подсказывает вот такую конструкцию:

где $SleepTimeout - переменная с числом секунд до перезапуска.
Если не нажата никакая кнопка и счетчик после приращения одной единицы меньше, чем таймаут, просто ждем одну секунду. Если какое-либо из этих условий не выполняется, выходим из while, и идем к команде перезапуска. Все бы ничего, первую итерацию скрипт проходит на ура, а вот дальше начинаются проблемы. На второй и последующих итерациях скрипт считает, что "любая кнопка" уже нажата, и ничего не ждет, уходя на следующую итерацию. Сразу же. Понятное дело, что проблема кроется где-то в двух условиях.
Проверяем. counter послушно сбрасывается при каждой итерации скрипта, так что дело не в нем. Остается только $Host.UI.RawUI.KeyAvailable, статус которой не обновляется. Значит, надо как-то сбросить его принудительно. Как? Учитывая, что это буфер клавиатуры, нужно его обнулить. А обнуляется он вот так:
$Host.UI.RawUI.FlushInputBuffer()

После добавления этой строки все стало работать так, как задумывалось.

@музыка: клац-клац-клац

@темы: PowerShell, Scripting

Комментарии
22.02.2018 в 20:02

Дяденька, спасибо тебе большое за науку! Забугорские прогеры рекомендуют юзать Raw.ReadKey, а у меня с ним прогресс в виде точек ломался. А Flush'ем и красота, и функциональность! Мерсибо!