C#で外部アプリを起動してアプリの標準出力を取得する方法 - USIのGUI開発の基本
USIプロトコルのGUIがやってることをやる方法です。
たとえば、将棋所がmisaki.exeをUSIエンジンとして呼び出すとして、misaki.exeに「usi」を標準入力で与えてやると
printf("id name misaki\n"); printf("id author Program Writer\n"); printf("option name UseBook type check default %s\n", isUseJoseki ? "true" : "false"); printf("usiok\n");
といった文字列を標準出力に返すようになっている。
C#のGUIからは、
Processを作ってmisaki.exeを呼び出し、
OutputDataにイベントハンドラーを登録して非同期に受信文字列をrichTextに貼り付けるようにしておく
プロセスの標準入力に「usi」と出力する
process.StandardInput.WriteLine("usi");
と、usiを受け取ったmisaki.exeが、結果を標準出力に排出し、それがイベントとなって、
process_DataReceivedが呼び出され、結果がrichTextに張り付く。
namespace hikaru { public partial class Form1 : Form { public Form1() { InitializeComponent(); Process process = new Process(); process.StartInfo.FileName = "main.exe"; process.StartInfo.UseShellExecute = false; process.StartInfo.CreateNoWindow = true; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardInput = true; process.OutputDataReceived += new DataReceivedEventHandler(process_DataReceived); process.Start(); process.BeginOutputReadLine(); richTextBox1.AppendText("SEND:usi"); process.StandardInput.WriteLine("usi"); process.StandardInput.Close(); } private void process_DataReceived(object sender, DataReceivedEventArgs e) { if (!String.IsNullOrEmpty(e.Data)) { richTextBox1.AppendText("RECV:" + e.Data); } } } }
実際にやってみると、ちゃんとusiの返事が返ってくるだけど、無限ループで何度も何度も帰ってくるんですよねえ(^^;
usiを出してる部分はループしてるわけじゃないんだけど? 受信イベントが永遠に発生している?