質問: p.StandardError.Read() MsgBox(output + errorStrings) End Sub End Class ``` ○プロセス終了 ![画像の説明をここに入力](https://i.stack.imgur.com/t6l4v.png)
回答: `p.StandardOutput.Read`(および`ReadLine`)メソッドは実際に入力(外部プロセスから見れば出力)があるまで現在のスレッドをブロックしてしまうので、フォームアプリ等のメインスレッドで使用してはいけません。 非同期に読み込みを行うには`ReadAsync`メソッドを使ったり、別スレッドを起こして`Read`/`ReadLine`したりといった方法がありますが、手軽なのは`BeginOutputReadLine`を使ってイベントとして入力を受け取ることかと思います。 とりあえず下記コードで入出力はできることは確認しました。 それと、VB.NETにおいて`"\r\n"`は改行コードを意味しません。文字通り`\r\n`という文字列を書き込んでいるだけになってますのでそこも修正しています。 ``` Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load '起動するファイルを指定する Dim command As String = "C:\xampp\mysql\bin\mysql.exe" p.StartInfo.FileName = command p.StartInfo.UseShellExecute = False p.StartInfo.RedirectStandardInput = True p.StartInfo.RedirectStandardOutput = True p.StartInfo.RedirectStandardError = True p.SynchronizingObject = Me ' 標準出力、標準エラーを受け取るとテキストボックスに追加する。 AddHandler Me.p.OutputDataReceived, Sub(s, dataReceivedEvent) Me.TextBox1.AppendText(dataReceivedEvent.Data & Environment.NewLine) End Sub AddHandler Me.p.ErrorDataReceived, Sub(s, dataReceivedEvent) Me.TextBox1.AppendText(dataReceivedEvent.Data & Environment.NewLine) End Sub p.Start() p.BeginOutputReadLine() p.BeginErrorReadLine() End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click p.StandardInput.WriteLine("show databases;") End Sub ``` 一般的には上記のコードで他のプロセスと入出力ができます。 質問では「例えばMySQLなど」となっていたので、一般的な回答としてはここまでです。 **MySQLについて** mysqlコマンドは出力がリダイレクトされると動きが変わります。出力を最適化するため、出力先がコンソールかどうか判断してわざわざ動きを変えているようです。 とりあえずわかった範囲でmysqlの現象と対処法です。 * 出力がバッファリングされる `--unbuffered`オプションをつけて起動すれば即フラッシュされるようになります。 * テーブルなどの出力時に罫線フォーマットされない `--table`オプションをつければ罫線つきになります。 * `\r`コマンドなどのエラー時にプロセスが終了してしまう? これは解決方法が見つかりませんでした。 ひとまず`p.Start()`の前に ``` p.StartInfo.Arguments = "-uuser -ppass --unbuffered --table" ``` のようにすればそれっぽく動きます。 参考: Super User: Different output when redirecting Stack Overflow: A bit curious about `mysql -e` output format with & without redirect GitHubGist: bashでパイプとかでつないでバッファされちゃう時