«前の日記(2011年02月06日) 最新 次の日記(2011年02月14日)» 編集

日々をアレコレ


2011年02月07日

.NETで別プロセスを起動して非同期でリダイレクトを取る その2

この間の続き。まず、1点修正。前のコードだと出力の受信イベントは発生しない。Process.Start()の後に、受信開始メソッドを呼ぶ必要がある。

p.Start();
p.BeginOutputReadLine(); // 受信開始

けど、それでも非同期でほぼリアルタイムなリダイレクトの取得が出来るという訳ではないようだ。というのも、Process.OutputDataReceivedイベントは、ストリームに行が書き込まれる、つまり、LFが出力されると発生する。たとえばプロセスの進捗を表すようなリダイレクトのように、CRを出力してカーソルを行頭に移動させて同一の行をを更新するような場合、CRの出力だけではイベントが発生しない。その場合、イベントは発生するのは進捗が100%まで到達したときだけのようだ。

なので、リアルタイムなリダイレクトの更新をするためには、ストリームを監視して、ストリームの末尾にカーソルが来ていないことを確認していく必要があるようだ。

private StreamReader output = null;
private Process proc = null;

private void StartProcess()
{
   proc = new Process();

    // プロセス開始のための情報
    proc.StartInfo.FIleName = "hogehoge.exe";         // 実行ファイル
    proc.StartInfo.UseShellExecute = false;           // シェルは利用しない
    proc.StartInfo.RedirectStandardOutput = ture;     // 出力リダイレクトを有効にする

    // プロセス終了イベントハンドラ登録
    proc.Exited += new EventHandler(procExited);

    output = proc.StandardOutpt;

    // プロセス開始
    proc.Start();

    // リダイレクト監視スレッド
    Thread t = new Thread(new ThreadStart(procGetOutput));
}

private void procGetOutput()
{
    while(!proc.HasExited)
    {
        if(!output.EndObStream)
        {
            string buf = output.ReadToEnd();
            // CRで分割して、最後をコンソールに出力
            string[] crlines = buf.Split('\r');
            Console.WriteLine(crlines[crlines.Length-1] + "\n");
        }
    }
}

«前の日記(2011年02月06日) 最新 次の日記(2011年02月14日)» 編集