Reputation: 52952
Writing a small command line tool, it would be nice to output in different colours. Is this possible?
Upvotes: 308
Views: 287525
Reputation: 1542
With this simple C# code you can demonstrate all possible output colors and choose what you want.
Type type = typeof(ConsoleColor);
Console.ForegroundColor = ConsoleColor.White;
foreach (var name in Enum.GetNames(type))
{
Console.BackgroundColor = (ConsoleColor)Enum.Parse(type, name);
Console.WriteLine(name);
}
Console.BackgroundColor = ConsoleColor.Black;
foreach (var name in Enum.GetNames(type))
{
Console.ForegroundColor = (ConsoleColor)Enum.Parse(type, name);
Console.WriteLine(name);
}
Upvotes: 5
Reputation: 2329
The easiest way I found to colorize fragments of the console output is to use the ANSI escape sequences in the Windows console.
public static int Main(string[] args)
{
string NL = Environment.NewLine; // shortcut
string NORMAL = Console.IsOutputRedirected ? "" : "\x1b[39m";
string RED = Console.IsOutputRedirected ? "" : "\x1b[91m";
string GREEN = Console.IsOutputRedirected ? "" : "\x1b[92m";
string YELLOW = Console.IsOutputRedirected ? "" : "\x1b[93m";
string BLUE = Console.IsOutputRedirected ? "" : "\x1b[94m";
string MAGENTA = Console.IsOutputRedirected ? "" : "\x1b[95m";
string CYAN = Console.IsOutputRedirected ? "" : "\x1b[96m";
string GREY = Console.IsOutputRedirected ? "" : "\x1b[97m";
string BOLD = Console.IsOutputRedirected ? "" : "\x1b[1m";
string NOBOLD = Console.IsOutputRedirected ? "" : "\x1b[22m";
string UNDERLINE = Console.IsOutputRedirected ? "" : "\x1b[4m";
string NOUNDERLINE = Console.IsOutputRedirected ? "" : "\x1b[24m";
string REVERSE = Console.IsOutputRedirected ? "" : "\x1b[7m";
string NOREVERSE = Console.IsOutputRedirected ? "" : "\x1b[27m";
Console.WriteLine($"This is {RED}Red{NORMAL}, {GREEN}Green{NORMAL}, {YELLOW}Yellow{NORMAL}, {BLUE}Blue{NORMAL}, {MAGENTA}Magenta{NORMAL}, {CYAN}Cyan{NORMAL}, {GREY}Grey{NORMAL}! ");
Console.WriteLine($"This is {BOLD}Bold{NOBOLD}, {UNDERLINE}Underline{NOUNDERLINE}, {REVERSE}Reverse{NOREVERSE}! ");
}
The output:
The NOBOLD
code is really "normal intensity". See the "SGR (Select Graphic Rendition) parameters" section on the linked wikipedia page for details.
The redirection test avoids outputting escape sequences into a file, should the output be redirected. If the user has a color scheme other than white-on-black, it won't get reset but you could maybe use the Console functions to save/restore the user's color scheme at the beginning and end of the program if that matters.
Upvotes: 34
Reputation: 1013
Here's an elegant implementation using the new string interpolation feature for dotnet.
[InterpolatedStringHandler]
public ref struct ConsoleInterpolatedStringHandler
{
private static readonly Dictionary<string, ConsoleColor> colors;
private readonly IList<Action> actions;
static ConsoleInterpolatedStringHandler() =>
colors = Enum.GetValues<ConsoleColor>().ToDictionary(x => x.ToString().ToLowerInvariant(), x => x);
public ConsoleInterpolatedStringHandler(int literalLength, int formattedCount)
{
actions = new List<Action>();
}
public void AppendLiteral(string s)
{
actions.Add(() => Console.Write(s));
}
public void AppendFormatted<T>(T t)
{
actions.Add(() => Console.Write(t));
}
public void AppendFormatted<T>(T t, string format)
{
if (!colors.TryGetValue(format, out var color))
throw new InvalidOperationException($"Color '{format}' not supported");
actions.Add(() =>
{
Console.ForegroundColor = color;
Console.Write(t);
Console.ResetColor();
});
}
internal void WriteLine() => Write(true);
internal void Write() => Write(false);
private void Write(bool newLine)
{
foreach (var action in actions)
action();
if (newLine)
Console.WriteLine();
}
}
To use it, create a class, such as ExtendedConsole
:
internal static class ExtendedConsole
{
public static void WriteLine(ConsoleInterpolatedStringHandler builder)
{
builder.WriteLine();
}
public static void Write(ConsoleInterpolatedStringHandler builder)
{
builder.Write();
}
}
Then, use it like:
var @default = "default";
var blue = "blue";
var green = "green";
ExtendedConsole.WriteLine($"This should be {@default}, but this should be {blue:blue} and this should be {green:green}");
Upvotes: 10
Reputation: 502
I developed a small fun class library named cConsole for colored console outputs.
Example usage:
const string tom = "Tom";
const string jerry = "Jerry";
CConsole.WriteLine($"Hello {tom:red} and {jerry:green}");
It uses some functionalities of C# FormattableString, IFormatProvider and ICustomFormatter interfaces for setting foreground and background colors of text slices.
You can see cConsole source codes here
Upvotes: 8
Reputation: 602
A sample method to color multiple words at the same time.
private static void WriteColor(string str, params (string substring, ConsoleColor color)[] colors)
{
var words = Regex.Split(str, @"( )");
foreach (var word in words)
{
(string substring, ConsoleColor color) cl = colors.FirstOrDefault(x => x.substring.Equals("{" + word + "}"));
if (cl.substring != null)
{
Console.ForegroundColor = cl.color;
Console.Write(cl.substring.Substring(1, cl.substring.Length - 2));
Console.ResetColor();
}
else
{
Console.Write(word);
}
}
}
Usage:
WriteColor("This is my message with new color with red", ("{message}", ConsoleColor.Red), ("{with}", ConsoleColor.Blue));
Output:
Upvotes: 7
Reputation: 192
I did want to just adjust the text color when I want to use Console.WriteLine();
So I had to write
Console.ForegroundColor = ConsoleColor.DarkGreen;
Console.WriteLine("my message");
Console.ResetColor();
every time that I wanted to write something
So I invented my WriteLine()
method and kept using it in Program class instead of Console.WriteLine()
public static void WriteLine(string buffer, ConsoleColor foreground = ConsoleColor.DarkGreen, ConsoleColor backgroundColor = ConsoleColor.Black)
{
Console.ForegroundColor = foreground;
Console.BackgroundColor = backgroundColor;
Console.WriteLine(buffer);
Console.ResetColor();
}
and to make it even easier I also wrote a Readline()
method like this:
public static string ReadLine()
{
var line = Console.ReadLine();
return line ?? string.Empty;
}
so now here is what we have to do to write or read something in the console:
static void Main(string[] args) {
WriteLine("hello this is a colored text");
var answer = Readline();
}
Upvotes: 0
Reputation: 7735
Here is a simple method I wrote for writing console messages with inline color changes. It only supports one color, but it fits my needs.
// usage: WriteColor("This is my [message] with inline [color] changes.", ConsoleColor.Yellow);
static void WriteColor(string message, ConsoleColor color)
{
var pieces = Regex.Split(message, @"(\[[^\]]*\])");
for(int i=0;i<pieces.Length;i++)
{
string piece = pieces[i];
if (piece.StartsWith("[") && piece.EndsWith("]"))
{
Console.ForegroundColor = color;
piece = piece.Substring(1,piece.Length-2);
}
Console.Write(piece);
Console.ResetColor();
}
Console.WriteLine();
}
Upvotes: 27
Reputation: 3876
Yes, it is possible as follows. These colours can be used in a console application to view some errors in red, etc.
Console.BackgroundColor = ConsoleColor.Blue;
Console.ForegroundColor = ConsoleColor.White;//after this line every text will be white on blue background
Console.WriteLine("White on blue.");
Console.WriteLine("Another line.");
Console.ResetColor();//reset to the defoult colour
Upvotes: 5
Reputation: 8142
Yes, it's easy and possible. Define first default colors.
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.White;
Console.Clear();
Console.Clear()
it's important in order to set new console colors. If you don't make this step you can see combined colors when ask for values with Console.ReadLine()
.
Then you can change the colors on each print:
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Red text over black.");
When finish your program, remember reset console colors on finish:
Console.ResetColor();
Console.Clear();
Now with netcore we have another problem if you want to "preserve" the User experience because terminal have different colors on each Operative System.
I'm making a library that solves this problem with Text Format: colors, alignment and lot more. Feel free to use and contribute.
https://github.com/deinsoftware/colorify/ and also available as NuGet package
Colors for Windows/Linux (Dark):
Upvotes: 20
Reputation: 365
Just to add to the answers above that all use Console.WriteLine
: to change colour on the same line of text, write for example:
Console.Write("This test ");
Console.BackgroundColor = bTestSuccess ? ConsoleColor.DarkGreen : ConsoleColor.Red;
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine((bTestSuccess ? "PASSED" : "FAILED"));
Console.ResetColor();
Upvotes: 8
Reputation: 26033
I've created a small plugin (available on NuGet) that allows you to add any (if supported by your terminal) color to your console output, without the limitations of the classic solutions.
It works by extending the String
object and the syntax is very simple:
"colorize me".Pastel("#1E90FF");
Both foreground and background colors are supported.
Upvotes: 73
Reputation: 4128
Above comments are both solid responses, however note that they aren't thread safe. If you are writing to the console with multiple threads, changing colors will add a race condition that can create some strange looking output. It is simple to fix though:
public class ConsoleWriter
{
private static object _MessageLock= new object();
public void WriteMessage(string message)
{
lock (_MessageLock)
{
Console.BackgroundColor = ConsoleColor.Red;
Console.WriteLine(message);
Console.ResetColor();
}
}
}
Upvotes: 79
Reputation: 839114
Yes. See this article. Here's an example from there:
Console.BackgroundColor = ConsoleColor.Blue;
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("White on blue.");
Upvotes: 395
Reputation: 1039438
class Program
{
static void Main()
{
Console.BackgroundColor = ConsoleColor.Blue;
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("White on blue.");
Console.WriteLine("Another line.");
Console.ResetColor();
}
}
Taken from here.
Upvotes: 170