Подсказка для да или нет - без повторения в новой строке, если неправильный ввод - PullRequest
0 голосов
/ 06 февраля 2020

У меня есть этот простой фрагмент кода в сценарии PS, где я хочу получить простой ответ «да» или «нет». Тогда я просто делаю if ($ answer -eq "y") {устанавливаем роли} и if ($ answer -eq "n") {не устанавливаем роли}

if ($roles -eq "1") {
do {
$answer = read-host -prompt "Found missing roles. Install them now? (y/n)"
until ($answer -eq "y" or $answer -eq "n")
   }
}

Проблема в том, что когда пользователь вводит что-то, отличное от y или n, он перекомпоновывает новую строку. По сути, они могут продолжать нажимать клавишу ВВОД, и он просто заполнит им окно PS, а видимое меню будет прокручиваться за пределы экрана. Поэтому я тоже не хочу очищать экран.

Как я могу избежать новой строки и сделать код максимально простым и легким для понимания? Если есть простой или лучший способ выполнить sh это без do.. пока, тогда это хорошо, если это чисто и просто.

Ответы [ 3 ]

4 голосов
/ 06 февраля 2020

Попробуйте эту опцию ...

If ($Roles -eq '1') {
    $Cursor = [System.Console]::CursorTop
    Do {
        [System.Console]::CursorTop = $Cursor
        Clear-Host
        $Answer = Read-Host -Prompt 'Found missing roles. Install them now? (y/n)'
    }
    Until ($Answer -eq 'y' -or $Answer -eq 'n')
}

Редактировать : я закончил писать блог об этом вопросе и ответе. Вы можете прочитать это здесь: https://powershell.org/2020/02/forum-problem-to-posted-solution-and-article-post/

1 голос
/ 06 февраля 2020

Дайте этому шанс. Он берет координаты курсора перед вводом и затем перемещает его назад после ввода. Он будет работать независимо от того, где вы находитесь в вашем скрипте, и не повлияет на предыдущие строки.

if ($roles -eq "1") {
    Write-Host "Found missing roles. Install them now? (y/n): " -NoNewline
    do {
    #get current cursor positions before the Read-Host
    $x = $Host.UI.RawUI.CursorPosition.X
    $y = $Host.UI.RawUI.CursorPosition.Y

    $answer = Read-Host
    #set the cursor coordinates back to before the Read-Host
    $Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $x,$y
    }
    until ($answer -eq "y" -or $answer -eq "n")
    Write-Host ""
}
1 голос
/ 06 февраля 2020

Я сталкивался с похожими проблемами кодирования в PowerShell, и проблема, с которой я столкнулся, заключается в разных хостах (Normal PowerShell.EXE и PowerShell_ISE.EXE) и о том, как они по-разному обрабатывают пользовательский интерфейс. Например, вы можете прочитать клавишу с клавиатуры, используя $ Host.UI.RawUI.ReadKey (), но только в хосте PowerShell.EXE, а не в ISE. Без очистки экрана и повторного рисования вопроса у вас действительно не будет много жизнеспособных опций, которые работают в любых ситуациях.

Самый простой, самый элегантный способ обработки подобных ситуаций, на мой взгляд , это рассматривать скорее как проблему социальной инженерии, а не как проблему программирования. Я имею в виду, перефразируй свой вопрос, чтобы проверить рискованный вариант, а все остальное - безопасный вариант. В вашем случае, если установка дополнительных ролей должна выполняться только в случае крайней необходимости, перепишите ваш вопрос следующим образом:

if ($roles -eq "1") {
    $answer = read-host -prompt "Found missing roles. Press 'Y' to install them"
}

Затем, если $ answer -eq 'Y', выполните установку, в противном случае, независимо от что еще они печатают, не устанавливайте.

Если, однако, установка ролей там, где ненужные, не так уж плоха, вы можете переписать вопрос следующим образом:

if ($roles -eq "1") {
    $answer = read-host -prompt "Ready to install missing roles. Press 'N' to skip the installation."
}

В этом случае вы бы установили UNLESS, если пользователь вводит «N».

Иногда, как программисты, мы пытаемся решать человеческие проблемы с помощью большего количества кодирования, когда на самом деле человеческое решение гораздо проще.

Удачи .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...