「TIPS:コマンド・プロンプトを表示せずにコンソール・アプリケーションを実行するには?」では、Windowsアプリケーションなどから外部のコンソール・アプリケーションを実行する場合に、コマンド・プロンプトを表示させずに実行する方法について解説しているが、この際、実行する外部アプリケーションによっては、その画面出力がプログラムで必要になることがある。
本稿ではプログラムからコンソール・アプリケーションを実行し、その出力を取得する方法について解説する。
標準出力とそのリダイレクト
本題に入る前に、コンソール・アプリケーションの出力について簡単に説明しておこう。
たいていのコンソール・アプリケーションは実行結果などを画面(通常はコマンド・プロンプト)に表示するが、これはコンソール・アプリケーションが画面に描画を行っているわけではない。コンソール・アプリケーションは文字を「標準出力」に出力しているだけである(最終的にはコマンド・プロンプトが標準出力への出力内容を読み取って画面に文字を表示する)。
このため例えば、あらかじめコンソール・アプリケーションの標準出力への出力がファイルに書き込こまれるように設定して実行*すれば、コンソール・アプリケーション自体はそのままに、その出力先を画面からファイルへ切り替えることができる。このような出力先の切り替えは「リダイレクト」と呼ばれる。
*コマンド・プロンプト(cmd.exe)では、「>」記号により標準出力をファイルにリダイレクトできる。例えば「ipconfig.exe > result.txt」とすると、ipconfig.exeの実行結果がresult.txtというファイルに格納される。これは、シェルであるcmd.exeがipconfig.exeを実行する際にipconfig.exeの標準出力を読み込み、その出力をresult.txtというファイルに書き込んでいるためだ。
ProcessStartInfoクラスのRedirectStandardOutputプロパティ
プログラム内から実行したコンソール・アプリケーションの出力を取得するには、その標準出力をリダイレクトさせることにより可能となる。この設定は、プロセス起動時の設定情報となるProcessStartInfoクラス(System.Diagnostics名前空間)のRedirectStandardOutputプロパティで指定する。このプロパティをtrueに設定したProcessStartInfoオブジェクトを、外部アプリケーションを実行するためのProcess.Startメソッドに渡せばよい(下記のサンプル・コードを参照)。
なお、RedirectStandardOutputプロパティをtrueに設定した場合には、UseShellExecuteプロパティをfalseに設定しておく必要がある。
リダイレクトされた外部アプリケーションの出力は、プログラムではストリームとして読み出すことができる。このストリームはProcessクラス(System.Diagnostics名前空間)のオブジェクトのStandardOutputプロパティによりアクセスできる。
Processオブジェクトは、実行中のアプリケーション(=プロセス)を示すオブジェクトである。Process.Startメソッドによりアプリケーションの実行を開始した場合には、実行が開始されたアプリケーションを示すProcessオブジェクトをメソッドの戻り値として受け取ることができる。
コンソール・アプリケーションの出力を取り込むサンプル・コード
以下のコードは、コンソール・アプリケーションであるipconfig.exe(Windowsに標準搭載されている、ネットワーク設定情報を表示するためのコマンド)を、コマンド・プロンプトを表示せずに実行し、その出力を取り込むサンプル・コードだ。
例えばVisual StudioでWindowsアプリケーションを新規作成し、Windowsフォームに配置したボタンのClickイベント・ハンドラにこのコードをペーストして実行すれば、そのボタンをクリックしたときにipconfig.exeの実行結果が[出力]ウィンドウに表示される。
string command = @"c:\windows\system32\ipconfig.exe";
ProcessStartInfo psInfo = new ProcessStartInfo();
psInfo.FileName = command; // 実行するファイル
psInfo.CreateNoWindow = true; // コンソール・ウィンドウを開かない
psInfo.UseShellExecute = false; // シェル機能を使用しない
psInfo.RedirectStandardOutput = true; // 標準出力をリダイレクト
Process p = Process.Start(psInfo); // アプリの実行開始
string output = p.StandardOutput.ReadToEnd(); // 標準出力の読み取り
output = output.Replace("\r\r\n", "\n"); // 改行コードの修正
Debug.Write(output); // [出力]ウィンドウに出力
Dim command As String = "c:\windows\system32\ipconfig.exe"
Dim psInfo As New ProcessStartInfo()
psInfo.FileName = command ' 実行するファイル
psInfo.CreateNoWindow = True ' コンソール・ウィンドウを開かない
psInfo.UseShellExecute = False ' シェル機能を使用しない
psInfo.RedirectStandardOutput = True ' 標準出力をリダイレクト
Dim p As Process = Process.Start(psInfo) ' アプリの実行開始
Dim output As String = p.StandardOutput.ReadToEnd() ' 標準出力の読み取り
output = output.Replace(vbCr + vbCrLf, vbLf) ' 改行コードの修正
Debug.Write(output) ' [出力]ウィンドウに出力
このコードを記述する場合にはSystem.Diagnostics名前空間をインポートしている必要がある。
上記のコードは静的メソッドであるProcess.Startメソッドを利用するために、まずProcessStartInfoオブジェクトを作成してから外部アプリケーションを開始し、その後Processオブジェクトを得ているが、次のようにまずProcessオブジェクトを明示的に作成するような記述も可能である。
string command = @"c:\windows\system32\ipconfig.exe";
Process p = new Process();
p.StartInfo.FileName = command; // 実行するファイル
p.StartInfo.CreateNoWindow = true; // コンソールを開かない
p.StartInfo.UseShellExecute = false; // シェル機能を使用しない
p.StartInfo.RedirectStandardOutput = true; // 標準出力をリダイレクト
p.Start(); // アプリの実行開始
string output = p.StandardOutput.ReadToEnd(); // 標準出力の読み取り
output = output.Replace("\r\r\n", "\n"); // 改行コードの修正
Debug.Write(output); // [出力]ウィンドウに出力
Dim command As String = "c:\windows\system32\ipconfig.exe"
Dim p As New Process()
p.StartInfo.FileName = command ' 実行するファイル
p.StartInfo.CreateNoWindow = True ' コンソールを開かない
p.StartInfo.UseShellExecute = False ' シェル機能を使用しない
p.StartInfo.RedirectStandardOutput = True ' 標準出力をリダイレクト
p.Start() ' アプリの実行開始
Dim output As String = p.StandardOutput.ReadToEnd() ' 標準出力の読み取り
output = output.Replace(vbCr + vbCrLf, vbLf) ' 改行コードの修正
Debug.Write(output) ' [出力]ウィンドウに出力
処理内容は上記のサンプル・コードその1とまったく同じ。このコードを記述する場合にはSystem.Diagnostics名前空間をインポートしている必要がある。
このコードではProcessStartInfoオブジェクトの設定を、ProcessオブジェクトのStartInfoプロパティを通じて行う。ProcessStartInfoオブジェクトはProcessクラスにより暗黙的に作成される。
カテゴリ:クラス・ライブラリ 処理対象:Windows環境
使用ライブラリ:ProcessStartInfoクラス(System.Diagnostics名前空間)
使用ライブラリ:Processクラス(System.Diagnostics名前空間)
関連TIPS:コマンド・プロンプトを表示せずにコンソール・アプリケーションを実行するには?
Copyright© Digital Advantage Corp. All Rights Reserved.