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で間違ったデータが発生します。

スクリーンショット:

gitbashコンソール

gitbashコンソール

リダイレクトされたデータ

リダイレクトされたデータ

質問:

  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. フォームでコンソール出力を表示します。

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

    }
于 2012-12-18T08:18:33.090 に答える