Chrome remote desktop Console.ReadKey yelds System.ConsoleKey.Packet instead of keystroke

197 Views Asked by At

This is more of a curiosity to be completely honest.

Inside a console project I am developing I request input from the user in a looped form of this:

ConsoleKey response;

Console.Write("Write messages to log? [y/n] ");
response = Console.ReadKey(false).Key;

assume 4 cases: 
case 1: Pressing the 'y' key on a keyboard directly atached to the pc running the software.
case 2: Connecting from another computer trough remote desktop connection and pressing the 'y' key on that machine.
case 3: Using on screen keyboard and press the 'y' key trough clicking on it (remotely or locally had no difference)
case 4: Connecting from another machine (specifically a phone) trough chrome remote desktop and pressing the 'y' key.

In case 1, 2 and 3, 'response' will contain 'Y'. In case 4 'response' will instead contain System.ConsoleKey.Packet aka enum 231 PACKET key (used to pass Unicode characters with keystrokes).

I have tried the same thing trough a second pc and I noticed this behavior does not appear to occurr. The most interesting thing is that the console shows me this

Write messages to log? [y/n] y

From this I evince that the keystroke is indeed received but handled incorrectly by my code. I am at a loss as to how to proceed.

Console.ReadLine yelds the correct keystrokes but i would prefer to use Console.ReadKey if possible.

Is this specific behavior for phone keyboards? How would I obtain the actual key?

2

There are 2 best solutions below

1
On BEST ANSWER

How would I obtain the actual key?

The MSDN docs for ConsoleKey.Packet doesn't say anything useful, so I found references to ConsoleKey in the source which lead here. That's casting ir.keyEvent.virtualKeyCode to a ConsoleKey where ir is an InputRecord.

A quick google finds the WinApi equivalent is INPUT_RECORD, and chasing the docs through KEY_EVENT_RECORD leads to this doc of Virtual-Key codes, which contains some more docs for VK_PACKET:

Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP

The Remarks for KEYBDINPUT say:

INPUT_KEYBOARD supports nonkeyboard-input methods—such as handwriting recognition or voice recognition—as if it were text input by using the KEYEVENTF_UNICODE flag. If KEYEVENTF_UNICODE is specified, SendInput sends a WM_KEYDOWN or WM_KEYUP message to the foreground thread's message queue with wParam equal to VK_PACKET. Once GetMessage or PeekMessage obtains this message, passing the message to TranslateMessage posts a WM_CHAR message with the Unicode character originally specified by wScan. This Unicode character will automatically be converted to the appropriate ANSI value if it is posted to an ANSI window.

From my searching it doesn't look like .NET implements this mechanism for you, so you might have to do it yourself!

I'm afraid I've no idea why it's happening in your case however...

0
On

I just ran into this issue too! In my case, it only happened when connecting to my development pc from a phone as well. (I was using the RDP app)

Here's what I came up with today that works!

public static bool Confirm(string prompt)
{
    Console.Write($"{prompt} [y/n] ");

    char letter;
    do
    {
        letter = char.ToLower(Console.ReadKey(true).KeyChar);
    } while (letter != 'y' && letter != 'n');

    Console.WriteLine(letter);
    return letter == 'y';
}

Thanks for confirming that I'm not the only one with the issue!