lookat 发表于 2024-1-19 05:09

C#控制台内容重定向到richTextBox中

本帖最后由 lookat 于 2024-1-20 07:20 编辑

/////////////////////////////////////////////////////////////////////////////////////////////////
      /////////////////////////////////////////////////////////////////////////////////////////////////
      // 将控制台输出重定向到文本框 可过滤
      // 创建一个内存流来捕获控制台输出
      private MemoryStream consoleOutput = new MemoryStream();
      // 用于存储要过滤的关键字
      private string[] filterKeywords = { "当前字符数量", "最大字符数量", "当前字符数量百分比" };
      private void InitializeConsoleRedirection()
      {
            // 重定向控制台输出
            Console.SetOut(new StreamWriter(consoleOutput) { AutoFlush = true });
            // 设置一个定时器,定期检查控制台输出
            System.Timers.Timer timer = new System.Timers.Timer(1000);
            timer.Elapsed += (sender, e) => CheckConsoleOutput();
            timer.Start();
      }
      private void CheckConsoleOutput()
      {
            // 将流的位置重置到开始
            consoleOutput.Position = 0;
            // 读取流中的内容
            string output = new StreamReader(consoleOutput).ReadToEnd();
            // 如果有内容,则显示在RichTextBox中,并过滤关键字
            if (!string.IsNullOrEmpty(output))
            {
                string filteredOutput = FilterWholeLineContainingKeywords(output);
                // 由于richTextBox1的更新需要在UI线程中执行,所以使用Invoke方法
                richTextBox1.Invoke((MethodInvoker)(() =>
                {
                  richTextBox1.AppendText(filteredOutput);
                }));
            }
            // 清空流中的内容
            consoleOutput.SetLength(0);
      }
      //此方法过滤关键词整行
      private string FilterWholeLineContainingKeywords(string input)
      {
            //正则表达式来匹配包含关键词的行
            //此正则表达式不会删除/r/n换行 @"(?i)(?m)^(?=.*\b({0})\b).*"
            //此正则表达式会删除/r/n换行 @"(?im)^(?=.*\b({0})\b).*\r?\n?"
            string pattern = string.Format(@"(?im)^(?=.*\b({0})\b).*\r?\n?", string.Join("|", filterKeywords));
            //屏蔽包含关键词的字符串
            return Regex.Replace(input, pattern, string.Empty);
            //string replacement = "***"; // 用于替换整行的文本
            //返回值包含replacement替代的整行字符串
            //return Regex.Replace(input, pattern, replacement, RegexOptions.IgnoreCase);
      }
      //此方法仅过滤关键词
      private string FilterKeywords(string input)
      {
            // 使用正则表达式替换关键字
            foreach (string keyword in filterKeywords)
            {
                input = Regex.Replace(input, keyword, "***", RegexOptions.IgnoreCase);
            }
            return input;
      }
      //////////////////////////////////////////////////////////////////////////////////////////////
      //////////////////////////////////////////////////////////////////////////////////////////////
      

      // 将控制台输出重定向到文本框 不可过滤
      private void DisplayMessageInRichTextBox1()
      {
            // 将控制台输出重定向到文本框
            RichTextBox richTextBox = this.richTextBox1;
            Console.SetOut(new richTextBoxStreamWriter(richTextBox));
      }

      //添加消息进入RichTextBox1中
      private void DisplayMessageInRichTextBox(string message)
      {
            if (richTextBox1.InvokeRequired)
            {
                richTextBox1.Invoke(new MethodInvoker(delegate
                {
                  richTextBox1.AppendText(message + Environment.NewLine);
                }));
            }
            else
            {
                richTextBox1.AppendText(message + Environment.NewLine);
            }
      }

      //当richTextBox1内容被改变时
      private void richTextBox1_TextChanged(object sender, EventArgs e)
      {
            // 获取RichTextBox1的最大字符数量
            toolStripStatusLabel3.Text = richTextBox1.MaxLength.ToString();

            // 获取RichTextBox1的当前字符数量
            toolStripStatusLabel5.Text = richTextBox1.Text.Length.ToString();

            // 这里可以继续使用lengths数组
            // 计算当前字符数量占最大字符数量的百分比
            double percentage = Math.Round((double)richTextBox1.Text.Length / richTextBox1.MaxLength * 100, 2);

            // 检查是否达到最大值的70%
            if (percentage >= 70 && percentage <= 90)
            {
                // 字体颜色变为橘黄色
                toolStripStatusLabel4.ForeColor = Color.Orange;
                toolStripStatusLabel5.ForeColor = Color.Orange;
            }
            // 检查是否达到最大值的90%
            else if (percentage >= 90)
            {
                // 字体颜色变为红色
                toolStripStatusLabel4.ForeColor = Color.Red;
                toolStripStatusLabel5.ForeColor = Color.Red;
            }
            // 否则,字体颜色恢复为默认颜色
            else
            {
                toolStripStatusLabel4.ForeColor = Color.Green;
                toolStripStatusLabel5.ForeColor = Color.Green;
            }

            // 输出到控制台(或显示在文本框中)
            Console.WriteLine("当前字符数量: " + richTextBox1.Text.Length);
            Console.WriteLine("最大字符数量: " + richTextBox1.MaxLength);
            Console.WriteLine("当前字符数量百分比: " + percentage);
      }

//没有关键词屏蔽的
https://s11.ax1x.com/2024/01/20/pFE0ZtA.png


//仅屏蔽关键词的
https://s11.ax1x.com/2024/01/19/pFEpxGF.png

//关键词屏蔽整行包括换行的
https://s11.ax1x.com/2024/01/19/pFE9AIK.png




lookat 发表于 2024-1-20 07:56

这个办法和组件自带的文字检测可能出现死循环,但最新的帖子提供了完整的解决办法,小问题:https://www.52pojie.cn/thread-1882611-1-1.html

猫吃 发表于 2024-1-19 08:41

有什么作用吗?

lookat 发表于 2024-1-19 09:00

猫吃 发表于 2024-1-19 08:41
有什么作用吗?

基本上开发的时候测完程序后,正常使用没啥问题,就算抛异常都给简单描述或者不提示,给的提示很片面,之后说不准又难碰到这情况,提示框又丑又难看,然后就弄成这种每个抛了异常的提示部分都会输出控制台转发到常驻框里,看的舒服些,还直观看到出问题的原因,然后不想打包后显示出来的部分还能用关键词隐藏,退出的时候就输出成运行日志文件了,就是这心理活动才弄成这样{:1_924:}{:1_924:}{:1_924:}

yu520 发表于 2024-1-19 09:05

这个可以改成软件应用输出吗

lookat 发表于 2024-1-19 09:15

yu520 发表于 2024-1-19 09:05
这个可以改成软件应用输出吗

你可以根据你的使用情况改改,这些方法没有额外的扩展,功能全是基础自带的,移植就能用的{:17_1073:}

apull 发表于 2024-1-19 09:50

猫吃 发表于 2024-1-19 08:41
有什么作用吗?

比如在你的程序中隐藏运行控制台程序imp导入数据库,把控制台显示的内容显示到你的程序里。

byok 发表于 2024-1-19 11:44

感谢分享一下

ThemanRonin 发表于 2024-1-19 12:30

你应该放一些运行的效果图。要不然大家都不知道具体效果

dongwang_fl 发表于 2024-1-21 08:33


感谢分享
页: [1] 2
查看完整版本: C#控制台内容重定向到richTextBox中