Description
Description
I made a console application by changing the foreground color with the Console.ForegroundColor
property and outputting to the standard error output using Console.Error.WriteLine()
etc. However, when I run the application, the foreground color may appear unchanged in the console.
Reproduction Steps
- Create a console application (eg
experiment01.exe
) that satisfies the following conditions.- Change the foreground color with
Console.ForegroundColor
- Output to the standard error output by
Console.Error.WriteLine()
etc.
- Change the foreground color with
- Run
experiment01.exe > foo.txt
on the console (eg command prompt). (foo.txt
is any file name)
Expected behavior
Messages output to the standard error output are displayed on the console with the foreground color set by the Console.ForegroundColor
property.
Actual behavior
Regardless of the foreground color set by the Console.ForegroundColor
property, messages output to the standard error output are displayed in the default foreground color (white? gray?) on the console.
Regression?
According to Mark Lakata's comments on
a stack overflow post
, the issue was already there as of December 2012. The runtime version is unknown.
Known Workarounds
I don't know how to avoid it.
Configuration
- .NET: 6.0.14 and 7.0.3
- OS: Windows 10 Pro, Ver.22H2, build 19045.2604, experience Windows Feature Experience Pack 120.2212.4190.0
- Architecture: x64
Not sure if other configurations will have similar issues.
Other information
Sample program
How to use the sample program
- Build the source code described later to create an executable file (eg
experiment01.exe
). - Execute the built program from a console such as a command prompt, specifying that the standard output should be redirected. (eg
experiment01.exe > foo.txt
)
Sample source code
using System;
namespace Experiment.ConsoleStandatdErrorWithColor.Experiment01
{
/// <summary>
/// A test program to check the strange behavior of the Console class.
/// </summary>
internal class Program
{
private static void Main(string[] args)
{
// Back up the current foreground color before changing the foreground color.
var defaultColor = Console.ForegroundColor;
// Change the foreground color to blue.
Console.ForegroundColor = ConsoleColor.Blue;
// Display with "Console.WriteLine(string?)".
Console.WriteLine("This text is expected to be displayed in blue. (to default (==stdout))");
// Display with "Console.Out.WriteLine(string?)"
Console.Out.WriteLine("This text is expected to be displayed in blue. (to stdout)");
// Display with "Console.Error.WriteLine(string?)"
Console.Error.WriteLine("This text is expected to be displayed in blue. (to stderr)");
// Display the foreground color of the console.
Console.WriteLine($"The current console foreground color is \"{Console.ForegroundColor}\" (to stdout).");
Console.Error.WriteLine($"The current console foreground color is \"{Console.ForegroundColor}\" (to stderr).");
// Restore the foreground color.
Console.ForegroundColor = defaultColor;
}
}
// [Result]
// Only in case (2) below (that is, when standard output is redirected), the foreground color of characters displayed on the console is not changed.
//
// 1) If no redirect is done, the execution result will be displayed as follows:
//
// This text is expected to be displayed in blue. (to default (==stdout)) <= displayed in blue. (OK)
// This text is expected to be displayed in blue. (to stdout) <= displayed in blue. (OK)
// This text is expected to be displayed in blue. (to stderr) <= displayed in blue. (OK)
// The current console foreground color is "Blue" (to stdout). <= displayed in blue. (OK)
// The current console foreground color is "Blue" (to stderr). <= displayed in blue. (OK)
//
// 2) If the standard output is redirected to a file, the execution result will be displayed as follows.:
//
// This text is expected to be displayed in blue. (to stderr) <= Displayed in the default color. (NG)
// The current console foreground color is "Gray" (to stderr). <= Displayed in the default color. (NG)
//
// 3) If the standard error is redirected to a file, the execution result will be displayed as follows.:
//
// This text is expected to be displayed in blue. (to default (==stdout)) <= displayed in blue. (OK)
// This text is expected to be displayed in blue. (to stdout) <= displayed in blue. (OK)
// The current console foreground color is "Blue" (to stdout). <= displayed in blue. (OK)
//
// [Additional Info]
// Below is the URL of an article on "stack overflow".
// According to Mark Lakata's comments on this article, it appears that the issue already existed in December 2012.
// https://stackoverflow.com/questions/10532796/setting-the-color-for-console-error-writes
}
my findings
I suspect it's a problem with the setter for the property ForegroundColor
of the System.ConsolePal
class.
I have summarized the results of my consideration of this issue at the URL below, so please refer to it.
https://github.com/rougemeilland/Experiment.ConsoleStandatdErrorWithColor/blob/main/README.md
The URL of the project containing the above source code is as follows.
For this investigation, the program project for investigating the behavior of the Win32API used in the System.ConsolPal class can be found at the following URL.