重定向控制台输出(不是所有重定向的数据C#)

时间:2012-12-18 08:14:40

标签: c# redirect console

如果使用来自控制台的默认重定向

proc = new System.Diagnostics.Process();                    
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;

proc.OutputDataReceived += proc_OutputDataReceived;
proc.Exited += proc_Exited;
proc.ErrorDataReceived += proc_ErrorDataReceived;
proc.Start();
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();

存在问题(在Windows Git bash msysgit上测试)

  1. 在OutputDataReceived中并非所有数据。

  2. 在OutputDataReceived中没有来自文本颜色的数据。

  3. 在ErrorDataReceived中出错了数据。

  4. 截屏:

    git bash console

    git bash console

    重定向数据

    redirected data

    问题:

    1. 通过重定向可以获得正确的数据吗?

    2. 还有另一种从控制台获取正确数据的方法吗?

2 个答案:

答案 0 :(得分:1)

我找不到正确的重定向控制台输入和输出。

我的任务解决方案:

  1. 运行控制台应用程序。

    Process proc = new System.Diagnostics.Process();
    proc.StartInfo.FileName = "cmd.exe";
    proc.StartInfo.Arguments = "";
    proc.StartInfo.WorkingDirectory = "";
    proc.StartInfo.UseShellExecute = true;
    proc.StartInfo.CreateNoWindow = false;
    
    proc.Start();
    
    int count = 0;
    //wait console
    while (proc.MainWindowHandle == IntPtr.Zero)
    {
        Thread.Sleep(50);
        count++;
        if (count == 50)
            return;
    }
    
  2. 允许复制粘贴到控制台。

    //Attach to console
    DllImport.ConsoleFunctions.AttachConsole(proc.Id);
    //Get console output handle
    IntPtr cHandleO = DllImport.GetStdHandle(-11);
    //Set Quick edit Mode mode
    DllImport.SetConsoleMode(cHandleO, 0x0040);
    //Deattach from console
    DllImport.FreeConsole();
    
  3. 在表单上查看控制台输出。

    //Set my Panle as console window parent 
    DllImport.SetParent(proc.MainWindowHandle, panelConsole.Handle);
    DllImport.SendMessage(proc.MainWindowHandle, 0x0112, 0xF030, 0);
    //Resize
    DllImport.SetWindowPos(proc.MainWindowHandle, IntPtr.Zero, 0, 0, panelConsole.Width,     
        panelConsole.Height, 0x0040);
    //Hide border and title
    DllImport.SetWindowLong(proc.MainWindowHandle, -16, 0x10000000 | 0x00200000);
    
  4. 将命令从TextBox发送到控制台。

    private DllImport.INPUT_RECORD[] PrepareData(string data)
    {
        DllImport.INPUT_RECORD[] rec = new DllImport.INPUT_RECORD[data.Length + 1];
        for (int i = 0; i < data.Length; i++)
        {
            rec[i].EventType = 0x0001;
            rec[i].KeyEvent = new DllImport.KEY_EVENT_RECORD();
            rec[i].KeyEvent.bKeyDown = true;
            rec[i].KeyEvent.dwControlKeyState = 0;
            rec[i].KeyEvent.UnicodeChar = data[i];
            rec[i].KeyEvent.wRepeatCount = 1;
            rec[i].KeyEvent.wVirtualKeyCode = data[i];
            rec[i].KeyEvent.wVirtualScanCode = (ushort) DllImport.MapVirtualKey(data[i], 0);
        }
        rec[data.Length].EventType = 0x0001;
        rec[data.Length].KeyEvent = new DllImport.KEY_EVENT_RECORD();
        rec[data.Length].KeyEvent.bKeyDown = true;
        rec[data.Length].KeyEvent.dwControlKeyState = 0;
        rec[data.Length].KeyEvent.UnicodeChar = '\n';
        rec[data.Length].KeyEvent.wRepeatCount = 1;
        rec[data.Length].KeyEvent.wVirtualKeyCode = '\n';
        rec[data.Length].KeyEvent.wVirtualScanCode = (ushort) DllImport.MapVirtualKey(0x0D, 0);
    
        return rec;
    }
    
    uint count = 0;
    //Fttach to console
    DllImport.AttachConsole(proc.Id);
    //Get input handle
    IntPtr cHandleI = DllImport.GetStdHandle(-10);
    //Prepare data
    DllImport.INPUT_RECORD[] data = PrepareData(tb.Text);
    //Write to console
    DllImport.WriteConsoleInput(cHandleI, data, data.Length, out count);
    //Deattach
    DllImport.FreeConsole();
    
  5. Use PInvoke.net for some functions

    Sample project

答案 1 :(得分:0)

StreamWriter输入;         过程p = new Process();         private void Form1_Load(object sender,EventArgs e)         {

        p = new Process();
        p.StartInfo.FileName = ConfigurationManager.AppSettings["exe"];
        p.StartInfo.UseShellExecute = false;//自定义shell
        p.StartInfo.CreateNoWindow = true;//避免显示原始窗口
        p.StartInfo.RedirectStandardInput = true;//重定向标准输入(原来是CON)
        p.StartInfo.RedirectStandardOutput = true;//重定向标准输出
        p.StartInfo.RedirectStandardError = true;//重定向错误输出流
        p.OutputDataReceived += new DataReceivedEventHandler(Process_OutputDataReceived);
        p.ErrorDataReceived += new DataReceivedEventHandler(Process_OutputDataReceived);

        try
        {
            p.Start();//GO
            input = p.StandardInput;//重定向输入
            p.BeginOutputReadLine();//开始监控输出(异步读取)
        }
        catch (Win32Exception ) {
            MessageBox.Show("指定的可执行文件无效");
            Close();
        }

    }