Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I manipulate console cursor position in dotnet core?

Tags:

c#

.net

.net-core

How do I manipulate console cursor position in dotnet core?

As far as I can see in https://github.com/dotnet/corefx/blob/master/src/System.Console/src/System/Console.cs there is no way to manipualte cursor position.

Does it mean that it's impossible on windows and will be possible on linux via ANSI escape sequences?

like image 822
AlfeG Avatar asked Sep 18 '15 06:09

AlfeG


1 Answers

In ConsolePal class you have private static IntPtr OutputHandle(that is the handle of the console on which you want to move the cursor), so int this class you have to expose a method to set the cursor position. In this method you have to call system API SetConsoleCursorPosition(IntPtr hConsoleOutput, COORD cursorPosition);. COORD is:

[StructLayout(LayoutKind.Sequential)]
internal struct COORD
{
    internal short X;
    internal short Y;
} 

You can add DllImport of the previous method in Interop.mincore class (because it seems that is here where system DllImport are made), so somewhere where you want you can:

internal partial class Interop
{
    internal partial class mincore
    {
        [DllImport("kernel32.dll", SetLastError=true)]
        internal static extern bool SetConsoleCursorPosition(IntPtr hConsoleOutput, COORD cursorPosition);
    }
}

The method to expose in ConsolePal can look like this:

public static void SetCursorPosition(int left, int top)
{
    IntPtr consoleOutputHandle = OutputHandle;
    COORD cursorPosition = new COORD {
        X = (short) left,
        Y = (short) top
    };
    Interop.mincore.SetConsoleCursorPosition(consoleOutputHandle, cursorPosition;
}

Note: add to the method some input check and some check on Interop.mincore.SetConsoleCursorPosition returned value

And in Console class simply expose a method that call ConsolePal.SetCursorPosition

public static void SetCursorPosition(int left, int top)
{
     ConsolePal.SetCursorPosition(left, top);
}

I didn't test the code above so it may contain errors.

Edit

As @Jcl stated, it may not be welcome to use a custom version of .NET. In this case you can write a simple class to move the cursor(even this solution is only for Windows):

static class MyAwesomeConsoleExtensions
{
    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr GetStdHandle(int nStdHandle);
    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool SetConsoleCursorPosition(IntPtr hConsoleOutput, COORD cursorPosition);
    [StructLayout(LayoutKind.Sequential)]
    private struct COORD
    {
        internal short X;
        internal short Y;
    }
    private const int STD_OUTPUT_HANDLE = -11;

    public static void SetCursorPos(int left, int top)
    {
        IntPtr consoleOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
        COORD cursorPosition = new COORD
        {
            X = (short)left,
            Y = (short)top
        };
        SetConsoleCursorPosition(consoleOutputHandle, cursorPosition);
    }
}
like image 99
Matteo Umili Avatar answered Sep 28 '22 16:09

Matteo Umili