0

如果从控制台使用默认重定向

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 中出现错误数据。

屏幕截图:

git bash 控制台

git bash 控制台

重定向数据

重定向数据

问题:

  1. 有没有办法通过重定向获得正确的数据?

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

4

2 回答 2

2

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

我的任务解决方案:

  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. 在 Form 上查看控制台输出。

    //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();
    

将 PInvoke.net 用于某些功能

示例项目

于 2012-12-19T20:54:38.343 回答
0

StreamWriter 输入;进程 p = new Process(); 私人无效Form1_Load(对象发送者,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();
        }

    }
于 2012-12-18T08:18:33.090 回答