DOBON.NET DOBON.NETプログラミング掲示板過去ログ

EXEからDOSコマンドを実行、結果(DOSプロンプトに表示される内容)を取得するには

環境/言語:[VB.NET WIN2000]
分類:[.NET]

こんばんは、すーです。
表題の通りのご質問です。

例えば、pingコマンドをDOS画面で打つと
============================
C:\>ping 192.168.0.3

Pinging 192.168.0.3 with 32 bytes of data:

Reply from 192.168.0.3: bytes=32 time<1ms TTL=30
Reply from 192.168.0.3: bytes=32 time=1ms TTL=30
Reply from 192.168.0.3: bytes=32 time=1ms TTL=30
Reply from 192.168.0.3: bytes=32 time=1ms TTL=30

Ping statistics for 192.168.0.3:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 1ms, Average = 0ms
============================
となりますが、EXEからpingコマンドを実行し
上記のような結果をそのままStringとして取得し、
プログラム側で、処理したいのです。
普通のshell関数だと、このような結果は取得できないようなのですが、
なにかよい方法はありませんでしょうか。

また、いろいろ調べ下記のようなコードを書いて見ましたが、
実行時にフォームがもうひとつ立ち上がってしまいます。
それも併せてご教授いただけないでしょうか。
====================================================================
Private Sub cmdPing_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles cmdPing.Click

Dim p As New Process()
With p.StartInfo
.WindowStyle = ProcessWindowStyle.Hidden
.FileName = "PING"
.Arguments = Me.ip.Text
.RedirectStandardOutput = True
.UseShellExecute = False
.CreateNoWindow = True
End With
p.Start()
p.WaitForExit(1000)
Trace.WriteLine(Me.txtPingRslt.Text)
p.Dispose()

End Sub


ip     :IPアドレス入力テキストボックス
txtPingRslt:ping結果出力テキストボックス
====================================================================

よろしくお願いします。
すーさん、こんばんは。

System.Diagnostics.ProcessStartInfoを使うと解決しますよ。

例:
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
以下略

こんな感じで使用してください。

以前、同じ目的でping実行結果を取得するモジュールを作った事があるので、
昼ごろ迄待っていただければ、私のサイトにてアップします。
すーです。ありがとうございます。
下記コードで、
プロセススタート時の一行目
(DOSプロンプト起動時に表示される
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.)
は取得できたのですが、
pingを打っていると思われる次行以降でとまってしまいました。
ネットワーク系のコマンドの実行結果を取得するには、
処理結果が戻ってくるまで、何らかの待ち処理を入れなければいけない
だろう事は想像がつきますが、どうすれば実現できるかがわかりませんでした。

====================================================================
Private Sub cmdPing_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles cmdPing.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
psi.ErrorDialog = True
'コマンドラインを指定("/c"は実行後閉じるために必要)
psi.Arguments = "ping 192.168.0.3"

'起動
Dim p As Process = Process.Start(psi)
'出力を読み取る
While p.HasExited = False

results = p.StandardOutput.ReadLine
'出力された結果を表示
Me.txtRslt.Text = results & results

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

p.Dispose()

End Sub
====================================================================

>昼ごろ迄待っていただければ、私のサイトにてアップします。
待ちます!
よろしくお願いします。

ぱっとテストした感じでは、

psi.Arguments = "ping 192.168.0.3"

psi.Arguments = "c/ ping 192.168.0.3"

と、

results = p.StandardOutput.ReadLine

results = p.StandardOutput.ReadToEnd

の箇所を書き換えて、While文を削ったら動作しました。
すーさん、ihcioyさん、おはようございます。

アップしました。ちょっと古いソースなので、綺麗なコーディングではないかも(-_-;)
マルチポストはやめましょう
■No5037に返信(kenさんの記事)
> マルチポストはやめましょう
が〜〜〜ん!ショック!…(´・ω・`)ショボーン
頑張って過去ソース引っ張って、使いやすいように加工したのに…まぁ、いいや。コンテンツ追加する口実になったし…
■No5043に返信(ぺがらぼさんの記事)
> ■No5037に返信(kenさんの記事)
>>マルチポストはやめましょう
> が〜〜〜ん!ショック!…(´・ω・`)ショボーン
> 頑張って過去ソース引っ張って、使いやすいように加工したのに…まぁ、いいや。コンテンツ追加する口実になったし…

あらら、マルチポストだったのですね。
まぁ解決報告でも挙がればそんなに気にしませんが・・・。

ぺがらぼさんのソース拝見しました。
使い易く加工してあってすばらしいと思います。
すーです。
まず、お詫びいたします。
マルチポストであったことは認識しておりました。
申し訳ありません。
一処で解決できなかったのでこうしてご質問させていただいた次第です。


ぺがらぼさんには、ソースをいただきありがとうございます。
しかし、やはり問題は解決出来ませんでした。

ボタンを押すとWindowsフォームが立ち上がってしまい、またpingの結果も取得できませんでした。
また、いただいたソースを拝見させていただいた限りでは、取得できる結果は
pingの成否のみで、
============================
C:\>ping 192.168.0.3

Pinging 192.168.0.3 with 32 bytes of data:

Reply from 192.168.0.3: bytes=32 time<1ms TTL=30
Reply from 192.168.0.3: bytes=32 time=1ms TTL=30
Reply from 192.168.0.3: bytes=32 time=1ms TTL=30
Reply from 192.168.0.3: bytes=32 time=1ms TTL=30

Ping statistics for 192.168.0.3:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 1ms, Average = 0ms
============================
の内容を取得する事は出来ないように思われます。
せっかくいただいたのに申し訳ありません。

どうしても
'起動
Dim p As Process = Process.Start(psi)

部分で、もうひとつフォームが立ち上がってしまいます。
フォームは、DOSプロンプトの画面ではなく、windowsフォームです。
原始的だけども・・・

Shell関数で最小化実行&リダイレクトでファイルに出力
 ↓
出力されたファイルをRead

って方法はダメかな?かな?
ぺがらぼさんおつかれー
■No5070に返信(すーさんの記事)
> すーです。
> まず、お詫びいたします。
> マルチポストであったことは認識しておりました。
> 申し訳ありません。
> 一処で解決できなかったのでこうしてご質問させていただいた次第です。
>
>
> ぺがらぼさんには、ソースをいただきありがとうございます。
> しかし、やはり問題は解決出来ませんでした。
>
> ボタンを押すとWindowsフォームが立ち上がってしまい、またpingの結果も取得できませんでした。
> また、いただいたソースを拝見させていただいた限りでは、取得できる結果は
> pingの成否のみで、
> ============================
> C:\>ping 192.168.0.3
>
> Pinging 192.168.0.3 with 32 bytes of data:
>
> Reply from 192.168.0.3: bytes=32 time<1ms TTL=30
> Reply from 192.168.0.3: bytes=32 time=1ms TTL=30
> Reply from 192.168.0.3: bytes=32 time=1ms TTL=30
> Reply from 192.168.0.3: bytes=32 time=1ms TTL=30
>
> Ping statistics for 192.168.0.3:
> Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
> Approximate round trip times in milli-seconds:
> Minimum = 0ms, Maximum = 1ms, Average = 0ms
> ============================
> の内容を取得する事は出来ないように思われます。
> せっかくいただいたのに申し訳ありません。
>
> どうしても
> '起動
> Dim p As Process = Process.Start(psi)
>
> 部分で、もうひとつフォームが立ち上がってしまいます。
> フォームは、DOSプロンプトの画面ではなく、windowsフォームです。

OSはWindows 9x系ですか?説明にも記入しているとおり、9x系ではコマンドプロントが立ち上がってしまいます。
色々と試した事はありましたが、回避策が見つかっておりません。
ただ、NT系の場合は立ち上がりません。別に問題があるのではないですか?
サンプルソースをそのまま実行して見ましたか?

pingの結果についてですが、サンプルは成否を判定するようにしていますが、
ソース内にある、「buff = rs.ReadLine() '一行読み込む」
で示している通り、「rs」にはpingの結果が入っていますよ。
「buff」の中身をデバッグモードで確認して見ましたか?

とりあえず、サンプルソースをまずはそのまま実行してから質問してください。
あと、マルチポストにしている場合は、どこか判りませんが、面倒でも、あちらさんの方にも解決策を記述してくださいね。決してリンク先だけを記述するのはやめてください。それこそ失礼です。って今更言うことでは無いですね…
猫嶌さん、おはようございます。
> ぺがらぼさんおつかれー
サンクス(・∀・)
>ぺがらぼ さん

件の問題が解決いたしましたので、ご報告させていただきます。

マルチポスト先の掲示板で、プロジェクト名(生成されるEXE名)がpingであったため、フォームが立ち上がってしまうのではないか、というご指摘をいただき、
試したところ、

 @pTest
 Aping
というまったく同様の内容で、プロジェクト名が異なる物を作成し、
実行した結果、
 @フォームが立ち上がらず、pingの結果が取得できた。
 Aフォームが立ち上がり、pingの結果も取得できない。
でした。

使用OSはXPHomeおよびWin2kです。
ぺがらぼさんにいただいたソースでも、しっかり動作確認が出来ました。
今回の最大の問題は、プロジェクト名が「ping」であったことでした。
タスクマネージャで、実行時のプロセスをみると、
pTEST.exeでpingを実行したときに「PING.EXE」(本来のping用EXE)が起動していました。

プロセス起動を行うときには、作成するアプリ名にも気をつけなければいけないと言うことですね。

皆様、特にぺがらぼさんには、不快な思いをさせてしまい申し訳ありませんでした。
今後は注意いたします。
ありがとうございました。

DOBON.NET | プログラミング道 | プログラミング掲示板