2016-05-10 2 views
0

次のような状況があります。私はC#でProcess()を使用してバットファイルを実行する必要があり、リダイレクトする必要があります。私はそれを行う方法を知っているし、自分のプロセスにタイムアウトを使わないとコードが正常に動作する。したがって、プログラムはプロセスが終了するまで動作します(タイムアウト後にプロセスが強制終了されることが予想されます)。以下は私のコードです。C#RedirectStandardOutput出力とweaitforexit

Process TcRunner = new Process(); 
TcRunner.StartInfo.FileName = "cmd.bat"; 
TcRunner.EnableRaisingEvents = true; 
TcRunner.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
TcRunner.StartInfo.UseShellExecute = false; 
TcRunner.StartInfo.RedirectStandardOutput = true; 
TcRunner.StartInfo.RedirectStandardError = true; 

try 
{ 
    TcRunner.Start(); 
} 
catch (Exception ex) 
{ 
    Program.Print("Error: Could not start process\n"); 
    return 1; 
} 

string run_log_out = TcRunner.StandardOutput.ReadToEnd(); 
string run_log_err = TcRunner.StandardError.ReadToEnd(); 

if (!TcRunner.WaitForExit(5000) 
{ 
    //kill the process 
} 

try 
{ 
    StreamWriter run_out = new StreamWriter(@".\out"); 
    StreamWriter run_err = new StreamWriter(@".\err"); 
    run_out.WriteLine(run_log_out); 
    run_err.WriteLine(run_log_err); 
    run_out.Close(); 
    run_err.Close(); 
} 
catch (Exception e) 
{ 
    Console.WriteLine("Cannot open out/err for writing"); 
} 
+0

もう少し問題を説明できますか? –

+0

プログラムはラインでハングします 文字列run_log_out = TcRunner.StandardOutput.ReadToEnd(); まで処理が終了したら、waitoffxit(timeout)行に移動します。だから私はタイムアウト5秒と私のコマンドランタイムは10秒プロセスが殺されない場合 – Gayane

答えて

0

ストリームを同期して両方読みたい場合、デッドロックが発生する可能性があります。したがって、少なくとも1つのストリームを非同期的に読み取ろうとする必要があります。 ProcessStartInfo.RedirectStandardOutputためのVisualStudioのヘルプで

は、私はこの情報を見つけました:

// Do not perform a synchronous read to the end of both 
    // redirected streams. 
    // string output = p.StandardOutput.ReadToEnd(); 
    // string error = p.StandardError.ReadToEnd(); 
    // p.WaitForExit(); 
    // Use asynchronous read operations on at least one of the streams. 
    p.BeginOutputReadLine(); 
    string error = p.StandardError.ReadToEnd(); 
    p.WaitForExit(); 

このlinkは、彼らがイベントにメソッドを結合することによってasyncronously両方の流れを読んで良い例が、あります

... 
build.StartInfo.RedirectStandardOutput = true; 
build.StartInfo.RedirectStandardError = true; 
... 
build.ErrorDataReceived += build_ErrorDataReceived; 
build.OutputDataReceived += build_ErrorDataReceived; 
... 
build.BeginOutputReadLine(); 
build.BeginErrorReadLine(); 

static void build_ErrorDataReceived(object sender, DataReceivedEventArgs e) 
{ 
    ... 
}