将 ProcessStartInfo.StandardInputEncoding 设置为 UTF8 在输入开始处插入奇怪的字符?

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

我有一个在 .NET 5 (.NET Core) 上运行的 Winforms 应用程序,使用

richTextBox1
显示结果,使用
textBox1
编写 cmd。

这是代码:

public partial class Form1 : Form
{
    private Process m_proc;

    public Form1()
    {
        InitializeComponent();

        m_proc = new Process()
        {
            StartInfo = new ProcessStartInfo()
            {
                FileName = "cmd.exe",
                CreateNoWindow = true,
                UseShellExecute = false,
                ErrorDialog = false,
                RedirectStandardInput = true,
                RedirectStandardOutput = true,
                RedirectStandardError = true,

                //UTF8
                StandardInputEncoding = System.Text.Encoding.UTF8,
                StandardOutputEncoding = System.Text.Encoding.UTF8,
                StandardErrorEncoding = System.Text.Encoding.UTF8,
            },
            EnableRaisingEvents = true,
            SynchronizingObject = this
        };

        m_proc.OutputDataReceived += DoEvent_proc_OutputDataReceived;
        m_proc.ErrorDataReceived += DoEvent_proc_ErrorDataReceived;

        m_proc.Start();
        m_proc.BeginOutputReadLine();
        m_proc.BeginErrorReadLine();

        textBox1.KeyDown += DoEvent_tbConsole_KeyDown;
    }

    private void DoEvent_proc_ErrorDataReceived(object sender, DataReceivedEventArgs e)
    {
        richTextBox1.Invoke((MethodInvoker)delegate { 
            richTextBox1.AppendText(string.Concat("====> Error: ", e.Data));
            richTextBox1.AppendText(Environment.NewLine);
        });
    }

    private void DoEvent_proc_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        richTextBox1.Invoke((MethodInvoker)delegate { 
            richTextBox1.AppendText(e.Data);
            richTextBox1.AppendText(Environment.NewLine);
        });
    }
    private void DoEvent_tbConsole_KeyDown(object sender, KeyEventArgs e)
    {
        switch (e.KeyCode)
        {
            case Keys.Enter:
                e.Handled = true;
                e.SuppressKeyPress = true;//Clear 'ding' sound

                m_proc.StandardInput.WriteLine(textBox1.Text);

                textBox1.Clear();
                break;

            case Keys.Escape:
                Close();
                break;
        }
    }
}

当我在

textBox1
中输入文本“echo test”并按回车键时,我得到了结果:

Microsoft Windows [版本 6.3.9600] (c)

2013 微软公司。保留所有权利。

E: et5.0-windows>回声测试

====> 错误:“echo”未被识别为内部或外部命令,

====> 错误:可运行程序或批处理文件。

'echo' is not recognized as an internal or external command,
是因为程序在cmd
echo
之前插入了一些unicode文本(∩╗┐),所以程序没有将其视为
echo
而是视为
echo
。现在,如果我再次执行
echo test
,它会正常工作,因为奇怪的字符(∩╗┐)只在开头插入一次。

你可以在Notepad++中看到它奇怪的字体

Weird char

现在如果我删除代码

StandardInputEncoding = System.Text.Encoding.UTF8,

                ...                    
                //UTF8
                //StandardInputEncoding = System.Text.Encoding.UTF8, //Remove!!!!
                StandardOutputEncoding = System.Text.Encoding.UTF8,
                StandardErrorEncoding = System.Text.Encoding.UTF8,
                ...

它会工作得很好(它不会再插入奇怪的字符(∩╗┐)了)

Microsoft Windows [版本 6.3.9600] (c)

2013 微软公司。保留所有权利。

E: et5.0-windows>回声测试

测试

所以我看到问题是

StandardInputEncoding
,我需要将
StandardInputEncoding
设置为UTF8,以便我可以将unicode字符传递给我的程序,但如果我这样做,那么第一个cmd总是失败(因为它在开始)。我试图找到一种方法来清除开头的输入以清除那个奇怪的字符,但看起来它没有任何功能可以做到这一点,我尝试发送 Esc 键来清除那个奇怪的字符但仍然不起作用。我想知道为什么它首先插入奇怪的字符? (.NET Core 错误?)。我该如何解决这个问题?

c# windows winforms .net-core cmd
1个回答
0
投票

感谢 @Ralf,解决方案是:将

System.Text.Encoding.UTF8
替换为
new System.Text.UTF8Encoding(encoderShouldEmitUTF8Identifier: false)

所以代码应该是:

...
//UTF8
//StandardInputEncoding can't be System.Text.Encoding.UTF8, bc of Byte Order Mark bug
StandardInputEncoding = new System.Text.UTF8Encoding(encoderShouldEmitUTF8Identifier: false),
StandardOutputEncoding = System.Text.Encoding.UTF8,
StandardErrorEncoding = System.Text.Encoding.UTF8,
...
© www.soinside.com 2019 - 2024. All rights reserved.