是否可以在。net中以彩色方式写入控制台?

写一个小的命令行工具,用不同的颜色输出会很好。这可能吗?

201520 次浏览
class Program
{
static void Main()
{
Console.BackgroundColor = ConsoleColor.Blue;
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("White on blue.");
Console.WriteLine("Another line.");
Console.ResetColor();
}
}

取自在这里

是的。请看这个文章。这里有一个例子:

Console.BackgroundColor = ConsoleColor.Blue;
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("White on blue.");

enter image description here

上面的注释都是可靠的响应,但是注意它们不是线程安全的。如果您正在用多个线程写入控制台,更改颜色将添加一个竞争条件,可能会产生一些奇怪的输出。不过修复起来很简单:

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();
}
}
}

是的,这很简单,也有可能。定义第一个默认颜色。

Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.White;
Console.Clear();

Console.Clear()对于设置新的控制台颜色很重要。如果你不做这一步,你可以在请求Console.ReadLine()值时看到组合的颜色。

然后你可以改变每个打印的颜色:

Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Red text over black.");

当完成程序时,记得在完成时重置控制台颜色:

Console.ResetColor();
Console.Clear();

现在对于netcore,我们有了另一个问题,如果你想“保存”;用户体验,因为终端在每个操作系统上有不同的颜色。

我正在制作一个库,用文本格式解决这个问题:颜色,对齐和更多。请随意使用和贡献。

https://github.com/deinsoftware/colorify/,也可以作为NuGet包

Windows/Linux的颜色(暗):
enter image description here < / p >

MacOS颜色(光):
enter image description here < / p >

是的,可能如下所示。这些颜色可以在控制台应用程序中使用,以红色等方式查看一些错误。

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

我已经创建了一个小插件(在NuGet上可用),允许您在控制台输出中添加任何(如果您的终端支持)颜色,而不受经典解决方案的限制。

它通过扩展String对象来工作,语法非常简单:

"colorize me".Pastel("#1E90FF");

前景色和背景色都受支持。

enter image description here

只是在上面的答案中添加,所有都使用Console.WriteLine:来改变同一行文本的颜色,例如:

Console.Write("This test ");
Console.BackgroundColor = bTestSuccess ? ConsoleColor.DarkGreen : ConsoleColor.Red;
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine((bTestSuccess ? "PASSED" : "FAILED"));
Console.ResetColor();

下面是我编写的一个简单方法,用于编写带有内联颜色变化的控制台消息。它只支持一种颜色,但它符合我的需要。

// 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();
}

带有内联颜色变化的控制台消息图像

当我想使用Console.WriteLine();时,我只想调整文本颜色 所以我必须写

Console.ForegroundColor = ConsoleColor.DarkGreen;
Console.WriteLine("my message");
Console.ResetColor();

每次我想写点什么

所以我发明了我的WriteLine()方法,并一直在程序类中使用它而不是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();
}

为了让它更简单,我还写了一个Readline()方法,像这样:

public static string ReadLine()
{
var line = Console.ReadLine();
return line ?? string.Empty;
}

现在我们要做的就是在控制台中写入或读取一些东西:

static void Main(string[] args) {
WriteLine("hello this is a colored text");
var answer = Readline();
}

一种同时给多个单词上色的示例方法。

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);
}
}
}

用法:

WriteColor("This is my message with new color with red", ("{message}", ConsoleColor.Red), ("{with}", ConsoleColor.Blue));

输出:

enter image description here

我开发了一个名为cConsole的有趣的小类库,用于彩色控制台输出 示例用法:< / p >
const string tom = "Tom";
const string jerry = "Jerry";
CConsole.WriteLine($"Hello {tom:red} and {jerry:green}");
它使用c# FormattableString, IFormatProvider和ICustomFormatter接口的一些功能来设置文本切片的前景和背景颜色 你可以看到cConsole源代码在这里

下面是一个优雅的实现,它使用了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();
}
}

要使用它,创建一个类,例如ExtendedConsole:

internal static class ExtendedConsole
{
public static void WriteLine(ConsoleInterpolatedStringHandler builder)
{
builder.WriteLine();
}


public static void Write(ConsoleInterpolatedStringHandler builder)
{
builder.Write();
}
}

然后,像这样使用它:

        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}");

enter image description here