電子書籍の厳選無料作品が豊富!

コマンドプロンプトの出力をテキストボックスへ表示する方法について

現在、VBを使ったプログラミングを行っています。
以下に質問内容を示しますので、回答を宜しくお願いします。

<環境>
OS:Windows XP
開発ソフト:VB2008 express edition

質問:コマンドプロンプトの出力をテキストボックスへ表示する方法について

リダイレクトを使って、コマンドプロンプトの出力結果をVBのフォーム上(テキストボックス)
に表示したいのですが、常に出力が更新されるコマンドの場合、実行後にフリーズが起きてしまいます。

以下の例ではpingを送っていますが、テキストボックスには常にコマンドの出力結果が更新されません。(実行が終わるまで待つ必要がある)
理想としては、pingコマンドを実行したときの結果が、そのままテキストボックス上にリアルタイムに表示されることです。

リアルタイムにテキストボックスにコマンドプロンプトの結果を表示するには、
どのような設定が必要になるのでしょうか?
ご教授願います。宜しくお願いします。


----- 以下サンプルソース -----
Public Class Form1


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim results As String
Dim psi As New System.Diagnostics.ProcessStartInfo()

'ComSpecのパスを取得する
psi.FileName = System.Environment.GetEnvironmentVariable("ComSpec")
'出力を読み取れるようにする
psi.RedirectStandardInput = False
psi.RedirectStandardOutput = True
psi.UseShellExecute = False
'ウィンドウを表示しないようにする
psi.CreateNoWindow = True
'コマンドラインを指定("/c"は実行後閉じるために必要)
psi.Arguments = "/c ping 192.168.1.1"
'起動
Dim p As System.Diagnostics.Process = System.Diagnostics.Process.Start(psi)
'出力を読み取る
results = p.StandardOutput.ReadToEnd
'出力された結果を表示
TextBox1.Text = results

'WaitForExitはReadToEndの後である必要がある
'(親プロセス、子プロセスでブロック防止のため)
p.WaitForExit()
End Sub
End Class

A 回答 (3件)

ReadToEnd だと、出力が終わるまで待ってしまうので、


ReadLine か、Read を使ってループすればよいかと思います。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

ReadLineを使用したところ期待の動作が得られました!
ありがとうございました。
ただ、ループの終了条件に悩んでいますが、もう少し考えてみようと思います。
(とりあえず今はカウンタを設定しています)


----サンプルソース----

Public Class Form1


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim results As String
Dim temp As String
Dim psi As New System.Diagnostics.ProcessStartInfo()
Dim cnt As Integer
cnt = 0
temp = ""

'ComSpecのパスを取得する
psi.FileName = System.Environment.GetEnvironmentVariable("ComSpec")
'出力を読み取れるようにする
psi.RedirectStandardInput = False
psi.RedirectStandardOutput = True
psi.UseShellExecute = False
'ウィンドウを表示しないようにする
psi.CreateNoWindow = True
'コマンドラインを指定("/c"は実行後閉じるために必要)
psi.Arguments = "/c ping 192.168.1.1"
'起動
Dim p As System.Diagnostics.Process = System.Diagnostics.Process.Start(psi)

'Loop
Do
'出力を読み取る
results = p.StandardOutput.ReadLine

'出力された結果を表示
temp = temp + results
TextBox1.Text = temp

'すぐに返す
Application.DoEvents()
cnt = cnt + 1

Loop Until cnt = 100

'WaitForExitはReadToEndの後である必要がある
'(親プロセス、子プロセスでブロック防止のため)
p.WaitForExit()
End Sub
End Class

お礼日時:2010/05/08 11:15

これだけでテキストボックスの表示が


リアルタイムに変更できるかどうかは
不明ですが、経験でお答えします。

TextBox1.Text = results
の直後に
Application.DoEvents()
を入れるのは試されましたか?
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

試してみましたが、挙動は変わりませんでした。

お礼日時:2010/05/05 21:55

今ひとついい実装にならないのでメモだけ。


http://msdn.microsoft.com/en-us/library/system.d …

http://msdn.microsoft.com/en-us/library/system.d …
を組み合わせる。

#イベントの方でTextboxに対して書き出していく。なんかMono 2.6.4の実装だとカーソルの位置によって出力の表示位置がおかしくなる。

#cmd /c 192.168.1.1だと何も表示されず、
#psi.FileName = "ping.exe";psi.Arguments = "192.168.1.1";なら表示された。
#一応心配しなくても、データすべてが飛んでくるまで他の作業が出来ないということはなさそうだった。
#リファレンスにも書いてあるがBeginOutputReadLine()と通常のReadLine()は併用できない。

#どうしてもStartとExitのメソッドを分けざるを得なくなるんで落ち着かないんだけど、解決策が見つからず断念。

#とかまぁそんなことがあって、自分でわかりやすくコードを回答したりはしないです。ごめんね。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

MSDNを参考にして、もう少し勉強してみます。
ありがとうございました。

お礼日時:2010/05/05 21:51

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報