いつも↓こちらの様に Start して WaitForExit といういたってノーマルな使い方をしていますが、
@IT ほかのアプリケーションを実行してその終了を待つには?
調べてみるといろんなプロパティがあるもんですねぇ。
今回は、自分で作ったアプリケーション(ProcessTest)→自分で作ったアプリケーション(D:\ProcessTestApp.exe)と通信いたしました。
■参考文献
Process クラス
ProcessStartInfo クラス
■実行画像
画面の起動と同時に ProcessTestApp.exe を起動して、Button を押下すると ComboBox で選択されている値を ProcessTestApp.exe へ送ります。

ProcessTestApp.exe へ "e" を送ったところ。

■ProcessTest
Public Class ProcessTest
Private m_timer As System.Windows.Forms.Timer
Private Sub ProcessTest_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' '' 実行しているプロセスの一覧を取得する
'Dim procs As System.Diagnostics.Process() = System.Diagnostics.Process.GetProcesses()
'For Each proc As System.Diagnostics.Process In procs
' Console.WriteLine(proc.ProcessName)
'Next
'' ProcessInfo と Process の設定
Dim procStartInfo As ProcessStartInfo = New ProcessStartInfo()
With procStartInfo
' 起動するファイル名
.FileName = "D:\ProcessTestApp.exe"
' 引数
.Arguments = "ふじこ えでん オット"
' エラーの出力を Process オブジェクト.StandardError で取れるようにする
.RedirectStandardError = True
' 入力を Process オブジェクト.StandardInput で取れるようにする
.RedirectStandardInput = True
' 出力を Process オブジェクト.StandardOutput で取れるようにする
.RedirectStandardOutput = True
' リダイレクトするので OS のシェルは使用しない
.UseShellExecute = False
' 新しいウィンドウは作らない
.CreateNoWindow = True
.WindowStyle = ProcessWindowStyle.Hidden
End With
With Me.Process1
' ProcessStartInfo を関連付け
.StartInfo = procStartInfo
' Process 終了時に Exited イベントを発生させるか否か(既定:False)
' OnExited メソッドを使うとプログラムから Exited イベントの発生が可能
.EnableRaisingEvents = True
AddHandler .Exited, AddressOf OnProcessExited
'' 待機状態から抜けたときにプロセスの優先順位を動的に上げるか否か(既定:False)
'.PriorityBoostEnabled = False
' Exited イベントのイベント ハンドラ呼び出しをマーシャリングするために使用する ISynchronizeInvoke
.SynchronizingObject = Me
' 各ストリームに書き出された時のハンドラを追加する
AddHandler .ErrorDataReceived, AddressOf OnErrorDataRecieved
AddHandler .OutputDataReceived, AddressOf OnOutputDataReceived
' 開始
.Start()
'' Start のいろいろ(全部 Shared メソッド→インスタンス生成)
'Dim pass As System.Security.SecureString = New System.Security.SecureString()
'pass.AppendChar("p"c) : pass.AppendChar("a"c) : pass.AppendChar("s"c) : pass.AppendChar("s"c)
''Dim p As System.Diagnostics.Process = System.Diagnostics.Process.Start("ファイル名", "UserName", pass, "Domain")
'Dim p As System.Diagnostics.Process = System.Diagnostics.Process.Start("ファイル名", "引数", "UserName", pass, "Domain")
'Dim p As System.Diagnostics.Process = System.Diagnostics.Process.Start("ファイル名")
'Dim p As System.Diagnostics.Process = System.Diagnostics.Process.Start("ファイル名", "引数")
'Dim p As System.Diagnostics.Process = System.Diagnostics.Process.Start(procStartInfo)
' プロセスがアイドル状態になるまで待機する
' (UI とメッセージ ループを持つプロセスのみ)
'.WaitForInputIdle()
' 終了するまで無期限に待機する
'.WaitForExit()
' 非同期読み取り操作の開始
.BeginErrorReadLine()
.BeginOutputReadLine()
End With
'' Timer の設定
Me.m_timer = New System.Windows.Forms.Timer()
Me.m_timer.Interval = 5000
AddHandler Me.m_timer.Tick, AddressOf Timer_Tick
Me.m_timer.Start()
'' 入力部品の設定
Me.ComboBox1.DropDownStyle = ComboBoxStyle.DropDownList
Me.ComboBox1.Items.AddRange(New String() {"e", "x", "z"})
AddHandler Button2.Click, AddressOf Send
Dim tip As ToolTip = New ToolTip()
tip.IsBalloon = True
tip.SetToolTip(Me.Button2, "e:raise exception x:exit0 z:exit1")
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If Me.Process1.HasExited Then Return
Me.m_timer.Stop()
With Me.Process1
'' メインウィンドウが存在する場合に WM_CLOSE を送信
'.CloseMainWindow()
' 即時中断・メインウィンドウがない場合はこれで終了する
.Kill()
'' プロセスに関連付けられているリソースの解放
'.Close()
End With
End Sub
Private Sub Send(ByVal sender As Object, ByVal e As EventArgs)
If Me.Process1.HasExited Then Return
' ComboBox で選択された値を入力
Me.Process1.StandardInput.WriteLine(DirectCast(Me.ComboBox1.SelectedItem, String))
End Sub
Private Sub Timer_Tick(ByVal sender As Object, ByVal e As System.EventArgs)
If Me.Process1.HasExited Then
' 正常にしろ異常にしろ Process が終了してたら timer を Off
Me.m_timer.Stop()
Return
End If
With Me.Process1
' PriorityClass から算出される基本優先順位
Console.WriteLine("BasePriority:" & .BasePriority.ToString())
Console.WriteLine("PriorityClass:" & .PriorityClass.ToString())
' プロセス ID
Console.WriteLine("Id:" & .Id.ToString())
' ハンドル
Console.WriteLine("Handle:" & .Handle.ToString())
Console.WriteLine("MainWindowHandle:" & .MainWindowHandle.ToString())
' プロセスを実行しているコンピュータ名
Console.WriteLine("MachineName:" & .MachineName)
' メインウィンドウのキャプション
Console.WriteLine("MainWindowTitle:" & .MainWindowTitle)
' 名前
Console.WriteLine("ProcessName:" & .ProcessName)
' 関連付けられたプロセスのスレッドを実行できるプロセッサを示すビットマスク
Console.WriteLine("ProcessorAffinity:" & .ProcessorAffinity.ToString())
' ユーザーインターフェースが応答するか否か
Console.WriteLine("Responding:" & .Responding.ToString())
' ターミナル サービス セッション識別子
Console.WriteLine("SessionId:" & .SessionId.ToString())
' メインモジュール(ProcessModule 型)
Console.WriteLine("MainModule:" & .MainModule.ModuleName)
' 読み込まれたモジュール全て
Dim modules As ProcessModuleCollection = .Modules
For Each md As System.Diagnostics.ProcessModule In modules
Console.WriteLine("Module:" & md.ModuleName)
Next
' Thread
For Each th As ProcessThread In .Threads
Console.WriteLine("Thread:" & th.Id.ToString())
Next
' プロセスのワーキング セット(物理 RAM メモリ内でプロセスが現在参照できるメモリ ページのセット)
Console.WriteLine("MaxWorkingSet:" & .MaxWorkingSet.ToString())
Console.WriteLine("MinWorkingSet:" & .MinWorkingSet.ToString())
' 割り当てられたページングされないシステム メモリの量
' NonpagedSystemMemorySize は Obsolete
Console.WriteLine("NonpagedSystemMemorySize64:" & .NonpagedSystemMemorySize64.ToString())
' 割り当てられたページングされるシステム メモリの量
' PagedMemorySize は Obsolete
Console.WriteLine("PagedMemorySize64:" & .PagedMemorySize64.ToString())
' 割り当てられたページング可能なシステム メモリの量
' PagedSystemMemorySize は Obsolete
Console.WriteLine("PagedSystemMemorySize64:" & .PagedSystemMemorySize64.ToString())
' 使用される仮想メモリ ページング ファイル内のメモリの最大量
' PeakPagedMemorySize は Obsolete
Console.WriteLine("PeakPagedMemorySize64:" & .PeakPagedMemorySize64.ToString())
' 使用される仮想メモリの最大量
' PeakVirtualMemorySize は Obsolete
Console.WriteLine("PeakVirtualMemorySize64:" & .PeakVirtualMemorySize64.ToString())
' 使用される物理メモリの最大量
' PeakWorkingSet は Obsolete
Console.WriteLine("PeakWorkingSet64:" & .PeakWorkingSet64.ToString())
' 割り当てられたプライベート メモリの量
' PrivateMemorySize は Obsolete
Console.WriteLine("PrivateMemorySize:" & .PrivateMemorySize64.ToString())
' 割り当てられた仮想メモリの量
' VirtualMemorySize は Obsolete
Console.WriteLine("VirtualMemorySize64:" & .VirtualMemorySize64.ToString())
' カーネルコマンドを実行するための特権時間に費やした時間(TimeSpan 型)
Console.WriteLine("PrivilegedProcessorTime:" & .PrivilegedProcessorTime.TotalMilliseconds.ToString())
' 上記に該当する部分以外のコードを実行するのに費やした時間(TimeSpan 型)
Console.WriteLine("UserProcessorTime:" & .UserProcessorTime.TotalMilliseconds.ToString())
' PrivilegedProcessorTime + UserProcessorTime
Console.WriteLine("TotalProcessorTime:" & .TotalProcessorTime.TotalMilliseconds.ToString())
End With
End Sub
' プロセスが終了した時に発生
Private Sub OnProcessExited(ByVal sender As Object, ByVal e As System.EventArgs)
With Me.Process1
' 終了コード
System.Diagnostics.Debug.WriteLine("ExitCode:" & .ExitCode.ToString())
' 開始時刻
System.Diagnostics.Debug.WriteLine("StartTime:" & .StartTime.ToString("yyyy/MM/dd HH:mm:ss"))
' 終了時間
System.Diagnostics.Debug.WriteLine("ExitTime:" & .ExitTime.ToString("yyyy/MM/dd HH:mm:ss"))
End With
End Sub
' StandardError に書き込まれた時に発生
Private Sub OnErrorDataRecieved(ByVal sender As Object, ByVal e As System.Diagnostics.DataReceivedEventArgs)
System.Diagnostics.Debug.WriteLine("OnErrorDataRecieved:" & e.Data)
End Sub
' StandardOutput に書き込まれた時に発生
Private Sub OnOutputDataReceived(ByVal sender As Object, ByVal e As System.Diagnostics.DataReceivedEventArgs)
System.Diagnostics.Debug.WriteLine("OnOutputDataReceived:" & e.Data)
End Sub
End Class
■ProcessTestApp.exe のコード
'' ProcessTest 用
Module Module1
Function Main(ByVal args As String()) As Integer
If Not args Is Nothing Then
Console.Write("■ProcessTestApp■Arguments is :")
For Each arg As String In args
Console.Write(arg & " ")
Next
Console.WriteLine()
End If
Dim bk As System.ComponentModel.BackgroundWorker = _
New System.ComponentModel.BackgroundWorker()
AddHandler bk.DoWork, AddressOf DoWork
AddHandler bk.RunWorkerCompleted, AddressOf RunWorkerCompleted
bk.WorkerSupportsCancellation = True ' Cancel 可能に
bk.RunWorkerAsync()
Console.WriteLine("■ProcessTestApp■e:raise exception x:exit0 z:exit1")
Dim inputed As String = Console.ReadLine().ToLower()
bk.CancelAsync()
Select Case inputed
Case "e"
Throw New ApplicationException("えらーが発生した")
Case "z"
System.Environment.Exit(1) ' 終了コード 1
Case Else
System.Environment.Exit(0) ' 終了コード 0
End Select
End Function
' 非同期の仕事
Private Sub DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
Dim bk As System.ComponentModel.BackgroundWorker = _
DirectCast(sender, System.ComponentModel.BackgroundWorker)
For counter As Integer = 1 To 100
If bk.CancellationPending Then
' Cancel された
e.Cancel = True
Return
End If
System.Threading.Thread.Sleep(1000)
Console.WriteLine("□ProcessTestApp□DoWork :" & counter.ToString())
Next
End Sub
' 非同期の仕事が終わったとき
Private Sub RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)
If e.Cancelled Then
Console.WriteLine("□ProcessTestApp□RunWorkerCompleted :Cancelled")
ElseIf Not e.Error Is Nothing Then
Console.WriteLine("□ProcessTestApp□RunWorkerCompleted :Error Occurred")
Else
Console.WriteLine("□ProcessTestApp□RunWorkerCompleted :Completed")
End If
End Sub
End Module