別のプログラムでコンソール出力をテキストボックスにリダイレクトする

StackOverflow https://stackoverflow.com/questions/415620

質問

タスクを実行するために別のプログラムを呼び出す必要があるWindowsフォームアプリケーションを開発しています。このプログラムはコンソールアプリケーションであり、標準出力をコンソールからプログラムのTextBoxにリダイレクトする必要があります。

アプリケーションからプログラムを実行しても問題はありませんが、出力をアプリケーションにリダイレクトする方法がわかりません。イベントを使用してプログラムの実行中に出力をキャプチャする必要があります。

コンソールプログラムは、アプリケーションが停止し、テキストがランダムな間隔で絶えず変化するまで、実行を停止するものではありません。私がやろうとしているのは、コンソールからの出力をフックしてイベントハンドラーをトリガーするだけで、それを使用してTextBoxを更新できます。

C#を使用してプログラムをコーディングし、.NETフレームワークを使用して開発しています。元のアプリケーションは.NETプログラムではありません。

編集: ここに私がやろうとしていることのサンプルコードがあります。最後のアプリでは、Console.WriteLineをTextBoxを更新するコードに置き換えます。イベントハンドラーにブレークポイントを設定しようとしましたが、到達しませんでした。

    void Method()
    {
        var p = new Process();
        var path = @"C:\ConsoleApp.exe";

        p.StartInfo.FileName = path;
        p.StartInfo.UseShellExecute = false;
        p.OutputDataReceived += p_OutputDataReceived;

        p.Start();
    }

    static void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        Console.WriteLine(">>> {0}", e.Data);
    }
役に立ちましたか?

解決

これは私のために働く:

void RunWithRedirect(string cmdPath)
{
    var proc = new Process();
    proc.StartInfo.FileName = cmdPath;

    // set up output redirection
    proc.StartInfo.RedirectStandardOutput = true;
    proc.StartInfo.RedirectStandardError = true;    
    proc.EnableRaisingEvents = true;
    proc.StartInfo.CreateNoWindow = true;
    // see below for output handler
    proc.ErrorDataReceived += proc_DataReceived;
    proc.OutputDataReceived += proc_DataReceived;

    proc.Start();

    proc.BeginErrorReadLine();
    proc.BeginOutputReadLine();

    proc.WaitForExit();
}

void proc_DataReceived(object sender, DataReceivedEventArgs e)
{
    // output will be in string e.Data
}

他のヒント

次のコードを使用できます

        MemoryStream mem = new MemoryStream(1000);
        StreamWriter writer = new StreamWriter(mem);
        Console.SetOut(writer);

        Assembly assembly = Assembly.LoadFrom(@"C:\ConsoleApp.exe");
        assembly.EntryPoint.Invoke(null, null);
        writer.Close();

        string s = Encoding.Default.GetString(mem.ToArray());
        mem.Close();

多くのヘルパーメソッドを O2プラットフォーム(オープンソースプロジェクト)に追加しました。コンソールの出力および入力を介した別のプロセスとの相互作用( http://code.google.com/p/o2platform/source/browse/trunk/O2_Scripts/APIs/Windows/CmdExe/CmdExeAPI.cs

現在のプロセスのコンソール出力を(既存のコントロールまたはポップアップウィンドウで)表示できるAPIも役立つ場合があります。詳細については、このブログ投稿をご覧ください: http://o2platform.wordpress.com/2011/11/26/api_consoleout-cs-inprocess-capture-of-the-console-output/ (このブログにはコンソールの使用方法の詳細も含まれています新しいプロセスの出力)

時間を節約してくれたMarc Maxhamの回答に感謝します!

Jon of All Tradesが気づいたように、IOストリームをリダイレクトするには UseShellExecute をfalseに設定する必要があります。そうでない場合、 Start()呼び出しは InvalidOperationExceptionをスローします

ここで、 txtOut がWPF読み取り専用テキストボックスであるコードの私の修正です

void RunWithRedirect(string cmdargs)
{
    var proc = new Process()
    {
        StartInfo = new ProcessStartInfo("cmd.exe", "/k " + cmdargs)
        {
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            CreateNoWindow = true
        },
        EnableRaisingEvents = true
    };

    // see below for output handler
    proc.ErrorDataReceived += proc_DataReceived;
    proc.OutputDataReceived += proc_DataReceived;
    proc.Start();

    proc.BeginErrorReadLine();
    proc.BeginOutputReadLine();

    proc.WaitForExit();
}

void proc_DataReceived(object sender, DataReceivedEventArgs e)
{
    if (e.Data != null)
        Dispatcher.BeginInvoke(new Action( () => txtOut.Text += (Environment.NewLine + e.Data) ));
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top