C # arrow key for console application

I have a simple console application written in C #. I want to be able to detect arrow keystrokes, so I can allow the user to control. How to detect keydown / keyup events using a console application?

All my googling led to information on Windows Forms. I do not have a graphical interface. This is a console application (for controlling the robot via the serial port).

I have functions written to handle these events, but I have no idea how to register to actually receive the events:

private void myKeyDown(object sender, KeyEventArgs e) { switch (e.KeyCode) { case Keys.Left: ... case Keys.Right: ... case Keys.Up: ... } } private void myKeyUp(object sender, KeyEventArgs e) { ... pretty much the same as myKeyDown } 

This is probably really the main question, but I'm pretty new to C #, and I never had to enter this input before.

Update:. Many of them suggest using System.Console.ReadKey(true).Key . This will not help. I need to know the moment when the key is held, when it is released, while holding several keys at the same time. In addition, ReadKey is a blocking call, which means that the program will stop and wait for the key to be pressed.

Update: It seems that the only way to do this is to use Windows Forms. This is annoying because I cannot use it in a headless system. Requiring a Form GUI to enter keyboard input ... is silly.

But in any case, for posterity, here is my solution. I created a new form project in my .sln:

  private void Form1_Load(object sender, EventArgs e) { try { this.KeyDown += new KeyEventHandler(Form1_KeyDown); this.KeyUp += new KeyEventHandler(Form1_KeyUp); } catch (Exception exc) { ... } } void Form1_KeyDown(object sender, KeyEventArgs e) { switch (e.KeyCode) { // handle up/down/left/right case Keys.Up: case Keys.Left: case Keys.Right: case Keys.Down: default: return; // ignore other keys } } private void Form1_KeyUp(object sender, KeyEventArgs e) { // undo what was done by KeyDown } 

Note that if you hold the key, KeyDown will be called many times, and KeyUp will be called only once (when you release it). Therefore, you must handle repeated KeyDown calls gracefully.

+8
c # user-input console-application
source share
6 answers

A bit late, but here's how to access the keyboard state in a console application.

Please note that this is not all managed code, as it requires GetKeyState to import from User32.dll.

 /// <summary> /// Codes representing keyboard keys. /// </summary> /// <remarks> /// Key code documentation: /// http://msdn.microsoft.com/en-us/library/dd375731%28v=VS.85%29.aspx /// </remarks> internal enum KeyCode : int { /// <summary> /// The left arrow key. /// </summary> Left = 0x25, /// <summary> /// The up arrow key. /// </summary> Up, /// <summary> /// The right arrow key. /// </summary> Right, /// <summary> /// The down arrow key. /// </summary> Down } /// <summary> /// Provides keyboard access. /// </summary> internal static class NativeKeyboard { /// <summary> /// A positional bit flag indicating the part of a key state denoting /// key pressed. /// </summary> private const int KeyPressed = 0x8000; /// <summary> /// Returns a value indicating if a given key is pressed. /// </summary> /// <param name="key">The key to check.</param> /// <returns> /// <c>true</c> if the key is pressed, otherwise <c>false</c>. /// </returns> public static bool IsKeyDown(KeyCode key) { return (GetKeyState((int)key) & KeyPressed) != 0; } /// <summary> /// Gets the key state of a key. /// </summary> /// <param name="key">Virtuak-key code for key.</param> /// <returns>The state of the key.</returns> [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern short GetKeyState(int key); } 
+14
source share
 var isUp = Console.ReadKey().Key == ConsoleKey.UpArrow; 

or another example, just for your case:

 while (true) { var ch = Console.ReadKey(false).Key; switch(ch) { case ConsoleKey.Escape: ShutdownRobot(); return; case ConsoleKey.UpArrow: MoveRobotUp(); break; case ConsoleKey.DownArrow: MoveRobotDown(); break; } } 
+4
source share
 System.Console.ReadKey(true).Key == ConsoleKey.UpArrow 

You can put this in a spin, something like:

 while(Running) { DoStuff(); System.Console.ReadKey(true).Key == ConsoleKey.UpArrow Thread.Sleep(1) } 
+2
source share

code example:

  ConsoleKeyInfo kb = Console.ReadKey(); if (kb.Key == ConsoleKey.LeftArrow) Console.WriteLine("Left Arrow pressed"); 
0
source share

You can do it

 bool keyWasPressed = false; if (consolekey.avalable) { keyvar = console.readkey(true); keyWasPressed = true; } if(keyWasPressed) { //enter you code here using keyvar } else { //the commands that happen if you don't press anything } 
0
source share

I have the same problem as I found an interesting post here using tasks. The original post can be found here: C # Console Application - How do I always read input from the console?

I need to emulate the PWM output via raspberry GPIO (using mono C #) to check the LCD backlight. With two simple keys, I wanted to change the duty cycle (up / down) and an additional key to stop the program.

I tried this (variables):

 static ConsoleKeyInfo key = new ConsoleKeyInfo(); static int counter = 0; static int duty = 5; // Starts in 50% 

The main program:

 static void Main(string[] args) { // cancellation by keyboard string CancellationTokenSource cts = new CancellationTokenSource(); // thread that listens for keyboard input var kbTask = Task.Run(() => { while (true) { key = Console.ReadKey(true); if (key.KeyChar == 'x' || key.KeyChar == 'X') { cts.Cancel(); break; } else if (key.KeyChar == 'W' || key.KeyChar == 'w') { if (duty < 10) duty++; //Console.WriteLine("\tIncrementa Ciclo"); //mainAppState = StateMachineMainApp.State.TIMER; //break; } else if (key.KeyChar == 'S' || key.KeyChar == 's') { if (duty > 0) duty--; //Console.WriteLine("\tDecrementa Ciclo"); //mainAppState = StateMachineMainApp.State.TIMER; // break; } } }); // thread that performs main work Task.Run(() => DoWork(), cts.Token); string OsVersion = Environment.OSVersion.ToString(); Console.WriteLine("Sistema operativo: {0}", OsVersion); Console.WriteLine("Menú de Progama:"); Console.WriteLine(" W. Aumentar ciclo útil"); Console.WriteLine(" S. Disminuir ciclo útil"); Console.WriteLine(" X. Salir del programa"); Console.WriteLine(); // keep Console running until cancellation token is invoked kbTask.Wait(); } static void DoWork() { while (true) { Thread.Sleep(50); if (counter < 10) { if (counter < duty) Console.Write("─"); //Console.WriteLine(counter + " - ON"); else Console.Write("_"); //Console.WriteLine(counter + " - OFF"); counter++; } else { counter = 0; } } } 

When it is necessary to increase the work cycle, pressing the "W" key makes the main task to change the working day variable (duty); same with the "S" key to reduce. The program ends when you press the X key.

0
source share

Source: https://habr.com/ru/post/649815/


All Articles