【问题标题】:24-Bit Console Color ANSI Codes in CygwinCygwin 中的 24 位控制台颜色 ANSI 代码
【发布时间】:2020-06-03 04:22:48
【问题描述】:

我编写了这个简单的 C#/.NET Core 控制台应用程序代码,它输出一组 7x7x7 的颜色立方体,测试 24 位颜色而不是 256 色模式,以及我使用的自定义 TTF 字体,它源自“Ultimate Old School PC Font Pack”包含一些额外的 Unicode 块字符。

正如所见,它在 Windows 10 终端中运行良好,但在 Cygwin 中却很糟糕,尽管根据 Github (https://gist.github.com/XVilka/8346728) 应该支持它。

如果使用 [38m 或 [48m 代码的代码中的某些内容可能与使用 Cygwin.bat 或 Cygwin 的 mintty 的 Cygwin 不太兼容,那么关于可能出现什么问题的任何想法?

但是,正如您从第三张图片中看到的那样,它在 Mingw64/MSYS2 的 Mintty 中看起来还不错,但我更喜欢使用 Cygwin。如您所见,它以某种方式破坏了第三张图片中的三角形字符,即使我在 mintty 中将字符集设置为 UTF-8。

using System;
using System.Text;

namespace ConsoleColor
{
    public class App
    {
        //int[] colorMeta1 = { 0, 85, 170, 255 };
        int[] colorMeta2 = { 0, 43, 85, 127, 170, 213, 255 };

        public App()
        {
            int length = colorMeta2.Length;
            int index = 0;
            Encoding defaultEncoder = Console.OutputEncoding;
            Console.OutputEncoding = Encoding.UTF8;
            for (int r=0;r<length;r++)
            {
                for(int g=0;g<length;g++)
                {
                    for(int b=0;b<length;b++)
                    {
                        int r2 = colorMeta2[r];
                        int g2 = colorMeta2[g];
                        int b2 = colorMeta2[b];
                        int foregroundColor = (r2 == 255 || g2 == 255 || b2 == 255) ? 0 : 255;
                        Console.Write($"\u001b[38;2;{r2};{g2};{b2}m█");
                        Console.Write($"\u001b[38;2;{foregroundColor};{foregroundColor};{foregroundColor}m\u001b[48;2;{r2};{g2};{b2}m({r2.ToString().PadLeft(3, ' ')},{g2.ToString().PadLeft(3, ' ')},{b2.ToString().PadLeft(3, ' ')})");
                        Console.Write($"\u001b[38;2;{r2};{g2};{b2}m█");
                        Console.Write($"\u001b[38;2;{170};{170};{170}m");
                        Console.Write($"\u001b[48;2;{0};{0};{0}m");
                        index++;
                    }
                    Console.WriteLine();
                }
            }
            Console.WriteLine($"{index} total colors.");
            for (int a = 0x2580; a <= 0x259F; a++)
                Console.Write($"{(char)a}");
            for (int a = 0x25E2; a <= 0x25E5; a++)
                Console.Write($"{(char)a}");
            Console.WriteLine();
            Console.OutputEncoding = defaultEncoder;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            App app = new App();
        }
    }
}

命令提示符:

Windows 10 中来自 Cygwin 的 Cygwin 命令提示符或 Mintty 3.1.6:

Mintty 3.1.6 in Mingw64 来自 Windows 10 中的 MSYS2:

【问题讨论】:

  • 将薄荷糖 terminal type 更改为 xterm-directmintty-direct
  • @matzeri:在 Cygwin 安装中不起作用。查看有关 MSys2/MingW64 版本 mintty 的页面,它是 3.1.6(x86_64-pc-msys),而 Cygwin 版本是 mintty 3.1.6(x86_64-pc-cygwin)。如果我使用 Windows cmd.exe 命令提示符来“dotrun run >run1.txt”,然后在 Cygwin 终端上使用“cat run1.txt”,它可以工作,但“dotnet run”在 Cygwin 下无法使用相同的输出,事实上,输出有时会显示 msys2 版本的正确字符,有时不会在后续运行中显示,这似乎表明 dotnet 和 mintty 可能存在问题。
  • 我指的是 Mintty 的配置,而不是另一个包。点击 Mintty 窗口左上角的图标而不是Option-&gt; Terminal -&gt; Type
  • 我试过了,还是不行。

标签: c# cygwin ansi


【解决方案1】:

以下博客文章显示了需要做的事情。显然,仍然需要在 Windows 10 上的 .NET Core 控制台应用程序中进行一些 win32 调用,Cygwin/Mintty 才能正常工作。

https://www.jerriepelser.com/blog/using-ansi-color-codes-in-net-console-apps/

代码:

private const int STD_OUTPUT_HANDLE = -11;
private const uint ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004;
private const uint DISABLE_NEWLINE_AUTO_RETURN = 0x0008;

[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 void ConsoleInit()
{
    var iStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    if (!GetConsoleMode(iStdOut, out uint outConsoleMode))
    {
        Console.WriteLine("failed to get output console mode");
        Console.ReadKey();
        return;
    }

    outConsoleMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN;
    if (!SetConsoleMode(iStdOut, outConsoleMode))
    {
        Console.WriteLine($"failed to set output console mode, error code: {GetLastError()}");
        Console.ReadKey();
        return;
    }
}

这一行特别重要:

outConsoleMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN;

【讨论】:

  • 请注意,在 Mingw64/Msys2 下,输出字符编码似乎仍然存在零星行为,它有时可以正常工作,有时不能。但是,颜色代码问题是固定的。 Cygwin 没有字符编码问题,WSL 也没有。
猜你喜欢
  • 2015-04-25
  • 2011-09-11
  • 2011-03-17
  • 1970-01-01
  • 2015-01-10
  • 1970-01-01
  • 2021-01-02
  • 1970-01-01
相关资源
最近更新 更多