带颜色的重定向标准输出。怎么做才对?

问题描述 投票:0回答:0

我正在尝试使用颜色信息捕获控制台应用程序的输出。

如果控制台应用程序使用 ANSI 代码,我的代码处理它没问题。

但是我尝试运行的一些控制台应用程序会丢失颜色信息。

我到处寻找解决方案,但到目前为止,一无所获。

调用代码如下:

    si.FileName = @"<A Consola APP>";
    si.Arguments = "status";
    si.EnvironmentVariables["TERM"] = "xterm";

    si.WindowStyle = ProcessWindowStyle.Hidden;
    si.CreateNoWindow = true;
    si.UseShellExecute = false;
    si.RedirectStandardError = true;
    si.RedirectStandardOutput = true;
    si.StandardErrorEncoding = Encoding.GetEncoding("IBM437");
    si.StandardOutputEncoding = Encoding.GetEncoding("IBM437");

    proc.ErrorDataReceived += ConsoleDataReceived;
    proc.OutputDataReceived += ConsoleDataReceived;
    proc.EnableRaisingEvents = true;

    proc.Start();
    proc.BeginOutputReadLine();
    proc.BeginErrorReadLine();

这是从控制台应用程序处理 STDOUT 的部分:

/// <summary>
/// Processes the text received from the console.
/// </summary>
/// <param name="sender">The object that raised the event.</param>
/// <param name="e">The <see cref="DataReceivedEventArgs"/> that contains the data of the event.</param>
private void ConsoleDataReceived(object sender, DataReceivedEventArgs e)
{
    /*
     * Processes the text received from the console in a thread-safe manner.
     */
    this.InvokeEx(f => AddANSIText(e.Data + "\n"));
}

private void AddANSIText(string ansiText)
{
    try
    {
        var pos = 0;                                // the current position in the ANSI text
        var fg = TextTerminal.ForeColor;            // the default ForeColor
        var bg = TextTerminal.BackColor;            // the default BackColor
        var ms = rxANSICode.Matches(ansiText);      // all the ANSI codes in the text.

        foreach (Match match in ms)
        {
            /*
             *  Appends the block of text prior 
             *  to the current ANSI color code
             */
            var block = ansiText.Substring(pos, match.Index - pos);
            TextTerminal.AppendText(block, fg, bg);
            pos = match.Index + match.Length;

            /*
             * Gets the ANSI color code
             */
            var code = match.Groups["code"].Value;
            if (code == "0")
            {
                /*
                 * The ANSI color code "0" is a reset
                 */
                fg = TextTerminal.ForeColor;
                bg = TextTerminal.BackColor;
                continue;
            }

            /*
             * Gets the specified colors from the code
             */
            fg = GetColorFromCode(code, fg, ANSI_FG_Color);
            bg = GetColorFromCode(code, fg, ANSI_BG_Color);
        }

        /*
         * Processes any text remaining.
         */
        if (pos < ansiText.Length)
        {
            var block = ansiText.Substring(pos);
            TextTerminal.AppendText(block, fg, bg);
        }
    }
    catch (Exception)
    {
        throw;
    }
}

private Color GetColorFromCode(string code, Color currentColor, string[] ansiPalette)
{
    /*
     * If the color code isn't in the ANSI palette
     * returns the current color
     */
    var pos = Array.IndexOf(ansiPalette, code);
    Debug.WriteLine($"ANSI color code: {code} -- position in the palette: {pos}");
    if (pos == -1)
        return currentColor;

    /*
     * Returns the color from the palette
     */
    return palette[pos];
}
c# stdout
© www.soinside.com 2019 - 2024. All rights reserved.