I am trying to write a console app in VB.NET (VS Studio Community 2019 & .Net framework 4.8) I cannot get it to display ANSI Escape sequences correctly. I am aware of this suggestion and have applied it. (Makes no difference)
I am able to set colour using
Console.ResetColor()
Console.ForegroundColor = ConsoleColor.Red
and cursor positioning, using
Console.SetCursorPosition(origCol + x, origRow + y)
Console.Write(s)
When I try to do this
Console.WriteLine("\u001b[31mHello World!\u001b[0m")
It just prints it out raw without interpreting the ANSI Sequences.
Console.OutputEncoding = Text.Encoding.XXX
only gives me limited options for XXX, including Ascii, UTF8, 16, 32 and Unicode.
I have gone over This article on "Console Virtual Terminal Sequences", which seems to be Microsoft's term for ANSI Codes. This article refers to setConsoleMode.
There is also this snippet of C, for which I can find no equivalent in vb.net
// Set output mode to handle virtual terminal sequences
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hOut == INVALID_HANDLE_VALUE)
{
return GetLastError();
}
DWORD dwMode = 0;
if (!GetConsoleMode(hOut, &dwMode))
{
return GetLastError();
}
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if (!SetConsoleMode(hOut, dwMode))
{
return GetLastError();
}
I'm guessing that one of these two might be the answer to my problem, but I have no idea how to do anything with this info in VB.net.
The question title indicates the programming is VB.net. Yet this statement is shown
Console.WriteLine("\u001b[31mHello World!\u001b[0m")
in which the C# style unicode escape sequence, \u001b is used. VB does not support escape sequences. A proper VB statement using string interpolation and the ChrW Function would be:
Console.WriteLine($"{ChrW(&H1B)}[31mHello World!{ChrW(&H1B)}[0m")
There is also this snippet of C, for which I can find no equivalent in vb.net
This will require using the Platform Invoke (PInvoke) feature to call the native api functions. A direct conversion of the snippet is wrapped in the SetVT100Mode
method defined below. You can find the various constants in either the documentation or by looking at the examples at Pinvoke.net.
Imports System.Runtime.InteropServices
Module Module1
Private Const STD_INPUT_HANDLE As Int32 = -10
Private Const STD_OUTPUT_HANDLE As Int32 = -11
Private Const STD_ERROR_HANDLE As Int32 = -12
Private ReadOnly INVALID_HANDLE_VALUE As New IntPtr(-1)
Private Const ENABLE_VIRTUAL_TERMINAL_PROCESSING As UInt32 = &H4
Sub Main()
Const Esc As Char = ChrW(27)
If SetVT100Mode() = 0 Then
Console.WriteLine($"{Esc}[31mHello World!{Esc}[0m")
End If
Console.ReadLine()
End Sub
Private Function SetVT100Mode() As Int32
Dim hOut As IntPtr = GetStdHandle(STD_OUTPUT_HANDLE)
If hOut = INVALID_HANDLE_VALUE Then
Return Marshal.GetLastWin32Error()
End If
Dim mode As UInt32
If Not GetConsoleMode(hOut, mode) Then
Return Marshal.GetLastWin32Error()
End If
mode = mode Or ENABLE_VIRTUAL_TERMINAL_PROCESSING
If Not SetConsoleMode(hOut, mode) Then
Return Marshal.GetLastWin32Error()
End If
Return 0
End Function
<DllImport("kernel32.dll", SetLastError:=True)>
Private Function GetConsoleMode(ByVal hConsoleHandle As IntPtr, ByRef lpMode As UInteger) As Boolean
End Function
<DllImport("kernel32.dll", SetLastError:=True)>
Private Function SetConsoleMode(ByVal hConsoleHandle As IntPtr, ByVal dwMode As UInteger) As Boolean
End Function
<DllImport("kernel32.dll", SetLastError:=True)>
Private Function GetStdHandle(ByVal nStdHandle As Integer) As IntPtr
End Function
End Module