コマンド実行結果のリダイレクト方法

このQ&Aのポイント
  • コマンド実行時にプロンプトに表示される結果文字列を取得する方法について説明します。
  • プロセスが終了するまで待つことなく、実行中のプロセスの結果を参照する方法を紹介します。
  • 参考URL先の[プロセス名].StandardOutput.ReadToEndを使用する方法以外にも、処理進捗率を取得する方法についても解説します。
回答を見る
  • ベストアンサー

コマンド実行時の結果のリダイレクト

お世話になっております。 【環境】 作業マシン:WINDOWS Server2008 (仮想) 開発ツール:VWD2010(VB) 使用DB:SQLServer2008R2 Webフォームにてアプリを開発しております。 ASP.NET VBでの開発の経験はおおよそ4ヶ月程です。 【質問内容】 コマンド実行し、その際プロンプトに表示される結果文字列を、 下記を参考に取得しています。 http://dobon.net/vb/dotnet/process/standardoutput.html 実行しているのは処理終了までに5分くらい掛かるexeで、 10秒毎に現在の処理進捗率を吐きます。 ですが現在はプロセスが終了するまで結果の参照ができません。 参考URL先にあります、 [プロセス名].StandardOutput.ReadToEnd この取得方法ではプロセスの終了まで待たねばなりません。 完了していないプロセスのoutput を参照するには どのようにすればよいのでしょうか。 何卒ご教授下さい。

質問者が選んだベストアンサー

  • ベストアンサー
  • todo36
  • ベストアンサー率58% (728/1234)
回答No.2
wendy0303
質問者

お礼

todo36様 ありがとうございます。 プロセスの終了を待たない、という点で 以前に相談した質問と同じ考え方が出来たのですね。 今回は(リンク先スレッドで教えて頂いた)3番の方法、 非同期のスレッドを立てる方法で実現が出来ました。 1.メインスレッドでExeを実行。 2.リダイレクト処理を続けるサブスレッドを作成し、   リダイレクトされた内容をOutputreadlineで1行ずつ取り   セッション変数 (session("templog")) に格納。 3.メインスレッド側は定期的に session("templod") を参照し、画面を更新。 4.Exeを実行したプロセスが終了していたら、画面更新を終了 と、いったコードを書くことで、 目的である未完了のプロセスのリダイレクト表示 (現在実行中であることと、その進度の表示)を得る事ができました。 ありがとうございました。

その他の回答 (1)

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.1

>参考URL先にあります、 >[プロセス名].StandardOutput.ReadToEnd >この取得方法ではプロセスの終了まで待たねばなりません。 >完了していないプロセスのoutput を参照するには >どのようにすればよいのでしょうか。 StandardOutputプロパティのReadToEndメソッドではなく、 BeginOutputReadLineメソッドで非同期読み込みにしてみてはどうでしょうか? 使い方に関しては… http://msdn.microsoft.com/ja-jp/library/system.diagnostics.process.beginoutputreadline.aspx の解説を。

wendy0303
質問者

お礼

ありがとうございます。 少々難しく、未だ目的を果たすコードはかけておりませんが、 リンク先の解説やサンプルを参考に試してみます。

wendy0303
質問者

補足

ご報告です。非同期でのリダイレクト取得が出来ました。 ありがとうございます。しかし、実は根っこの目的というのが >処理終了までに5分くらい >10秒毎に現在の処理進捗率を吐きます このプロセスの現在の進捗を定期的に画面に表示 することなのです。 Outputreadlineの中身をセッションに持てば、 後は定期的に格納先の変数をみればよい、 と、考えて居たのですが画面を1度でも返した時点で サーバーコントロールも終了してしまい、 続きを取得・表示することは出来ませんでした。 この目的を果たすためには、何か他の方法を考える必要がありそうです。

関連するQ&A

  • VB2008でコマンド実行

    VB2008のフォームからボタンをクリックして、DOSコマンドを実行したいのですが うまくいきません。 http://dobon.net/vb/dotnet/process/standardoutput.html にあるサンプルをそのまま貼り付けて実行したら Console.WriteLine(results)の実行結果が空白になります。 Debugで見ると BasePriority = {"プロセスは終了しているため、要求された情報は利用できません。"} という表示があるのですが、このサイトのコメントでは、出来ると書いてあるので何が 悪いのか分かりません。 分かる方がいらっしゃったら教えてください。お願いします。

  • Process.Startの戻り値を後で取得

    お世話になっております。 作業マシン:WINDOWS Server2008 (仮想) 開発ツール:VWD2010(VB) 使用DB:SQLServer2008R2 にて、Webアプリを開発しております。 ASP.NET開発の経験はおおよそ1ヶ月半程です。 現在、Process.Startで外部exeを実行しております。 この外部実行ファイルは3分くらい掛かる処理で、 WaitForExit() で結果を待たずに 次の画面(待機用画面)に遷移しています。 処理が終了したら、待機画面から結果画面へと遷移させたいのですが、 プロセスの完了と、その結果(戻り値)を、 Process.Startをコールした画面以外で受け取る事が出来るのでしょうか。 WaitForExitを使用するならば、 素直に終了を待ち、終了後にExitCodeを取得、 Ret = Process.Start() で戻り値も取得できましたが… WaitForExit( ) をしない場合、どのようにして取得できるのでしょうか。 http://dobon.net/vb/dotnet/process/openfile.html こちら等、Process.Start 非同期 などのキーワードで出てくるのは Processを実行した同画面内での待機のケースが多く、 今自分が遭遇しているケースに応用するには どうにも自分の理解が追いつけず質問いたします。 実行する画面でプロセスIDを取得し、セッションに持たせ、 終了を判断したい画面でプロセスIDを元にチェックをする… と言うことも考えてみましたが、プロセスIDを頼りに、 終了したプロセスの戻り値を突き止める方法も見つからず (発想自体が間違っているかもしれません) 皆様のお力を貸して頂けないでしょうか。何卒よろしくお願いします。

  • VB.NETでDOSコマンドの複数実行

    VB.NETでバッチファイルを使わずにDOSコマンドの複数実行をしたいのですが、 試しに Dim results As String 'ComSpecのパスを取得する psi.FileName = System.Environment.GetEnvironmentVariable("ComSpec") '出力を読み取れるようにする psi.RedirectStandardInput = False psi.RedirectStandardOutput = True psi.UseShellExecute = False 'ウィンドウを表示しないようにする psi.CreateNoWindow = True 'コマンドラインを指定("/c"は実行後閉じるために必要) 'psi.Arguments = "/c " & asCmd & " /w" psi.Arguments = "/c " & "CD C:\" & " /w" '起動 p = System.Diagnostics.Process.Start(psi) '出力を読み取る results = p.StandardOutput.ReadToEnd '出力された結果を表示 Console.WriteLine(results) psi.Arguments = "/c " & "DIR" & " /w" '起動 p = System.Diagnostics.Process.Start(psi) '出力を読み取る results = p.StandardOutput.ReadToEnd '出力された結果を表示 Console.WriteLine(results) 'WaitForExitはReadToEndの後である必要がある '(親プロセス、子プロセスでブロック防止のため) p.WaitForExit() というプログラムを作成したのですが、DIRは実行されるのですが、 Cドライブに移動ができません。   何が悪いのでしょうか? 実現できる方法があればご教授ください。

  • コマンドプロンプトを終了せずにリダイレクトするには?

    コマンドプロンプトを終了せずにリダイレクトするには? VBからコマンドプロンプトを操作し、結果をLabelに貼り付けることを考えています。 しかし、コマンドプロンプトを起動するプロセスにリダイレクト設定をしたところ、実行するたびに終了してしまい、その後のコマンド入力でプロセスが見つからずエラーとなってしまいます。コマンドプロンプトは終了せずにリダイレクトの設定する方法を教えて頂けないでしょうか。 また、コマンドプロンプト自体は表示させずに実行できるのが理想なので、やり方のヒントだけでも頂けると助かります。 操作例(VBのボタンから):cmd.exe起動 → cd c:\ → dir エラー内容:プロセス 'c:\windows\system32\cmd.exe' が見つかりませんでした。 動作環境:VB2005、Windows XP ============================== Public Class Form1 Private Sub Button19_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button19.Click Dim P1 As New System.Diagnostics.Process P1.StartInfo.UseShellExecute = False P1.StartInfo.RedirectStandardOutput = True P1.StartInfo.FileName = "cmd.exe" P1.Start() End Sub Private Sub Button12_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button12.Click AppActivate("c:\windows\system32\cmd.exe") SendKeys.SendWait("CD c:\{Enter}") Label5.Text = P1.StandardOutput.ReadToEnd() End Sub Private Sub Button11_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button11.Click AppActivate("c:\windows\system32\cmd.exe") SendKeys.SendWait("DIR{Enter}") Label5.Text = P1.StandardOutput.ReadToEnd() End Sub

  • VB.NETでのDOSコマンドを実行について

    VB.NETでのDOSコマンドを実行について いつも大変お世話になっています。 VB.NET上でバイナリデータを DOSコマンド「copy」で結合させたいのですが うまくいきません。ご助言ください。 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 copy /b /y "C:\Program Files\test\Data\out0001.bin"+"C:\Program Files\test\Data\out0002.bin" "C:\Program Files\test\Data\TEST.jpg"" '※コマンドの前後のダブルクォーテーションを省き、コマンドプロンプトで ' 直接実行した場合は成功しました。 '起動 Dim p As System.Diagnostics.Process=_ System.Diagnostics.Process.Start(psi) '出力を読み取る results = p.StandardOutput.ReadToEnd '出力された結果を表示 Console.WriteLine(results) 'WaitForExitはReadToEndの後である必要がある '(親プロセス、子プロセスでブロック防止のため) p.WaitForExit()

  • コマンドプロンプトを表示せずにプロセスの起動

    VB.NETでソースファイルをJ2sk142(javac.exe)に渡してコンパイルの結果をコマンドプロンプトではなくVBのTextBoxに表示するプログラムを作成しています。 でも、プロセスを起動すると一瞬だけプロンプトが表示されます。 これを表示させない方法はありますでしょうか? With Process1 .StartInfo.FileName=JAVACPATH .StartInfo.Arguments=TextBox.Text .StartInfo.WorkingDirectory=ProPath .StartInfo.UseShellExecute = False .StartInfo.ErrorDialog = True .EnableRaisingEvents = True .StartInfo.RedirectStandardOutput = True .StartInfo.RedirectStandardError = True .StartInfo.WindowStyle = ProcessWindowStyle.Hidden End With Try Process1.Start() OutPutTextBox.Text &= Process1.StandardOutput.ReadToEnd OutPutTextBox.Text &= Process1.StandardError.ReadToEnd Process1.WaitForExit() Catch ex As Exception

  • C#でのbatファイル実行結果取得

    既存のbatファイルが存在し、C#プログラムより、実行結果コ-ドを取得したいのですが、どうやっても「0」が帰ってきましまい、悩んでいます。 よいアドバイス&指摘を下さい。 <batファイル>  @echo off  set RET_CODE=%1  echo %RET_CODE%  exit /b %RET_CODE% <C#プログラム>  ProcessStartInfo psInfo = new ProcessStartInfo();  psInfo.FileName = @"D:/app/Send.bat";  psInfo.Arguments = "45";  psInfo.CreateNoWindow = true;  psInfo.UseShellExecute = false;  psInfo.RedirectStandardOutput = true;  Process ps= Process.Start(psInfo);  string st = ps.StandardOutput.ReadToEnd(); ← 何も出ない?  ps.WaitForExit();  string rt = ps.ExitCode.ToString(); ← 必ず「0」が返却?

  • 子プロセスのコマンド結果

    pipe(),fork(),dup2()等を駆使し、子プロセスにコマンドを実行させる処理にて、 子プロセスの実行したコマンドが入力待ちか処理終了しているかを判定する方法ってありますで しょうか?

  • OSシャットダウン時の常駐アプリ終了について

    現在VB2005にて常駐アプリの開発を行っています。 OSはWindowsXPです。 起動はOS起動時にスタートアップより起動するのですが、 OSのシャットダウン時に常駐アプリが終了していない為、 「このプログラムからの応答がありません(待機、終了、キャンセル)」が表示されます。 この方法を回避するには、シャットダウンを常駐アプリ側で検知してアプリ自身が終了処理をすると思いますが、方法がよくわかっていません。 http://dobon.net/vb/dotnet/system/sessionending.html ↑のURLを参照してみたのですが、シャットダウン時にメッセージの表示はされるのですが、メッセージ表示部をアプリ終了処理に置き換えても、終了処理が行われませんでした。 どなたか、お分かりになる方ご教授いただければと思います。

  • シェルコマンドの実行を行いたい

    シェルコマンドの実行は system("***.exe"); で行えますけど、system関数は実行したexeファイルが閉じられるまで処理がとまってしまいますよね? system関数を呼んだ後すぐに処理を返したい時はどうしたらいいのでしょうか。 また、2つ連続で実行ファイルを実行したいときにはどうしたらいいでしょうか。 system("1.exe"); system("2.exe"); これでは1.exeが終了しないと2.exeが起動しません。 バッチファイルでも同じ事になりますよね。 同時に起動したいのです。どうしたらいいのでしょうか、systemで躓いたので、 spawnで試してみました。 #include <process.h> #include <stdio.h> int main(){ spawn(P_NOWAIT,"notepad"); printf("notepadが起動しました。"); return 0; } こうすればnotepadを閉じなくてもprintf文が実行されると思ったのですが、コンパイルすると 未解決の_spawnが_main内で参照されました。 外部参照1が未解決です。 とでます・・。 どなたか解決策を教えてください>< OS:XPです。