Powershell ReadKey () чувствителен к регистру - PullRequest
1 голос
/ 09 апреля 2020

В моем скрипте мне нужно получить 1 символ от пользователя и обработать его немедленно, без ожидания ввода. Кроме того, я хочу обработать символ с учетом регистра.

write-host("Please press a or A:")
$choice = ($host.UI.RawUI.ReadKey(('NoEcho,IncludeKeyUp,IncludeKeyDown'))).character

if($choice -ceq "a")
{
    write-host("You pressed a");
}
elseif($choice -ceq "A")
{
    write-host("You pressed A");
}
else
{
    Write-Host("You pressed neither a nor A")
}
Pause

Проблема этого кода в том, что когда я пытаюсь нажать «A», он показывает « Вы не нажали ни a, ни A * 1005». *». Причина в том, что нужно набрать «A». Сначала нужно нажать Shift , Powershell обнаруживает нажатие Shift и обрабатывает его немедленно, не дожидаясь A.

У кого-либо есть идеи как это решить?

Ответы [ 3 ]

1 голос
/ 09 апреля 2020

Соответствует ли приведенное ниже ожидаемому,

($key = $Host.UI.RawUI.ReadKey()) | % { if ($_.VirtualKeyCode -eq '16') {
            $key = $Host.UI.RawUI.ReadKey()
        }
        $Choice = $key.Character
        if ($Choice -ceq "a"){
            "`rYou pressed 'a'"
        }
        elseif ($Choice -ceq "A"){
            "`rYou pressed 'A'"
        }
        else {
            "`rYou neither pressed 'a' nor 'A'"
        }
    }
1 голос
/ 09 апреля 2020

Попробуйте следующий фрагмент кода:

if ( $Host.Name -eq 'ConsoleHost' ) {
    Write-Host "Please press a or A:"
    Do  {
            $choice = $host.UI.RawUI.ReadKey(14)
        } until ( $choice.VirtualKeyCode -in @( 48..90) )

    if ( $choice.Character -ceq "a") {
        Write-Host "You pressed a";
    }
    elseif ( $choice.Character -ceq "A") {
        Write-Host "You pressed A";
    }
    else {
        Write-Host "You pressed neither a nor A ($($choice.Character))";
    }
} else {
    # e.g. Windows PowerShell ISE Host:
    # the "ReadKey" method or operation is not implemented.
    Write-Host '$Host.Name -neq ConsoleHost' -ForegroundColor Magenta
}

Как написано в настоящее время, условие $choice.VirtualKeyCode -in @( 48..90) допускает некоторое (ограниченное) подмножество печатных символов. Отрегулируйте его относительно Ключи Enum

0 голосов
/ 09 апреля 2020

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

* 1007. *

Примечание. Хотя клавиши-модификаторы Shift , Control и Alt сами по себе не считаются нажатиями клавиш, комбинации с печатным символом делай; поэтому, например, Alt-a обрабатывается так же, как 'a', а Control-a в качестве управляющего символа START OF HEADING, U+0001.

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

# Wait for a printable character to be pressed, but only if not combined
# with Ctrl or Alt.
while (($key=$host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')).Character -eq 0 -or 
       $key.ControlKeyState -notin 0, 'ShiftPressed') {}
$char = $key.Character

Примечание: Это работает только на Windows - на Unix платформах, свойство .ControlKeyState, по-видимому, всегда 0.

Однако, если вместо этого вы используете [Console]::ReadKey(), вы можете заставить его работать на Unix -подобно платформам - что предполагает, что вы предполагаете, что ваш скрипт всегда выполняется в консоли (терминале), а не в других типах хостов PowerShell.

# Wait for a printable character to be pressed, but only if not combined
# with Ctrl or Alt.
while (($key = [Console]::ReadKey($true)).KeyChar -eq 0 -or 
       $key.Modifiers -notin 0, 'Shift') {}
$char = $key.KeyChar

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