-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Console.Foreground does not correctly set the color in every Terminal #62186
Comments
Tagging subscribers to this area: @dotnet/area-system-console Issue DetailsDescriptionWhen setting the output color with Console.Foreground not every terminal correctly displays the color. Reproduction Steps
Expected behaviorConsole.Foreground should correctly set the font color independent of terminal, or at least in all terminals that support font colors. Actual behaviorIn some terminals Console.Foreground works, in some it doesn't. Regression?No response Known WorkaroundsNone, see Actual behavior. ConfigurationNo response Other informationNo response
|
Have you compared other programs that writes different colors into console? Those console are implemented in very different ways, and will have different compatibility. |
I tried it in various terminals, but only with my small program written in the Reproduction Steps. |
Console in Windows and console in Unix are fundamentally different. Using control character is Unix-like way, and VSCode is more Unix-like. The others are mostly native Windows console. This may be a cross compatibility issue. |
It's hard to tell. ASP.NET Core outputs the color in VSC Debug Console correctly, so it either has some hidden secret sauce, or I'm missing something. |
It would be interesting to look at what aspnet is doing differently. |
Yes, I had similar issues in the past and I don't think anything has changed since then. Since about 6 months ago. Sometimes setting colors directly works. Sometimes sending ANSI codes works. Sometimes only basic ANSI codes work, sometimes also extended (like bold/italic/enhanced-color) codes work. Now, it's not so much a problem to put all in a helper function that uses different approaches for coloring, but in Core there is really no good way to determine "where you are", what is supported and what is not. That terminal information is provided by the operating system, as tools like compilers (gcc, clang, you name it) know exactly if they can print ANSI codes or not. Or if enhanced ANSI codes are supported. As far as I know ForegroundColor is Windows-only anyway. As are all cursor ("caret") features. Unification, or console feedback of supported features is really missing. Best would be if Core would emit ANSI when on non-Windows and the terminal supports it. Not just color, but cursor ("caret") movement as well. And then there is the new Terminal Window and all its issues with Core. |
If anyone's still having an issue with this, just printing the ANSI reset code near the start of the app boot fixed on Windows using the new terminal. Console.Write("\x1b[0m"); |
Any updates to this? I am interested in a clean way to change colors in VScode's Debug console |
Hi ! To do it, you can import some methods from kernel32.dll directly. public class TerminalSetup
{
// ReSharper disable InconsistentNaming
private const int STD_INPUT_HANDLE = -10;
private const int STD_OUTPUT_HANDLE = -11;
private const uint ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004;
private const uint DISABLE_NEWLINE_AUTO_RETURN = 0x0008;
private const uint ENABLE_VIRTUAL_TERMINAL_INPUT = 0x0200;
// ReSharper restore InconsistentNaming
[DllImport("kernel32.dll")]
private static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
[DllImport("kernel32.dll")]
private static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll")]
public static extern uint GetLastError();
public static void Setup()
{
var iStdIn = GetStdHandle(STD_INPUT_HANDLE);
var iStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (!GetConsoleMode(iStdIn, out uint inConsoleMode))
{
Console.WriteLine("failed to get input console mode");
Console.ReadKey();
return;
}
if (!GetConsoleMode(iStdOut, out uint outConsoleMode))
{
Console.WriteLine("failed to get output console mode");
Console.ReadKey();
return;
}
inConsoleMode |= ENABLE_VIRTUAL_TERMINAL_INPUT;
outConsoleMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN;
if (!SetConsoleMode(iStdIn, inConsoleMode))
{
Console.WriteLine($"failed to set input console mode, error code: {GetLastError()}");
Console.ReadKey();
return;
}
if (!SetConsoleMode(iStdOut, outConsoleMode))
{
Console.WriteLine($"failed to set output console mode, error code: {GetLastError()}");
Console.ReadKey();
return;
}
}
} |
Description
When setting the output color with Console.Foreground not every terminal correctly displays the color.
However if the color is set with unicode characters like \u001b[31m those terminals do show the correct color, meaning they do support color. (but some Terminals display the characters instead of the color making it not a functional workaround)
Reproduction Steps
Expected behavior
Console.Foreground should correctly set the font color independent of terminal, or at least in all terminals that support font colors.
Actual behavior
In some terminals Console.Foreground works, in some it doesn't.
In some terminals \u001b[31m works, in some it doesn't.
These two collections are not the same.
The user doesn't know in which type of terminal the code is running.
There is no way to consistently set color in the terminal.
Regression?
No response
Known Workarounds
None, see Actual behavior.
Configuration
No response
Other information
Tested on net6.0/Windows
The text was updated successfully, but these errors were encountered: