toagit
1/12/2016 - 5:21 AM

DOSコマンド非同期・同期サンプル

DOSコマンド非同期・同期サンプル


' * 実行中のプログラムのハンドルを取得
' *
Private Declare Function OpenProcess Lib "kernel32" ( _
      ByVal Access As Long _
    , ByVal Handle As Long _
    , ByVal taskId As Long _
) As Long

' *
' * ハンドルのExitを検出
' *
Private Declare Function GetExitCodeProcess Lib "kernel32" ( _
      ByVal Process As Long _
    , ByRef Code As Long _
) As Long

' *
' * ハンドルを閉じる
' *
Private Declare Sub CloseHandle Lib "kernel32" ( _
      ByVal Object As Long _
)

Public Sub Main()
	Dim taskId As Long
	taskId = ExecShell("copy C:\xxx D:\xxx")
	If IsActive(taskId) Then
		MsgBox(taskId & "実行中です。")
	End If

	Call Wait(taskId)

	If Not IsActive(taskId) Then
		MsgBox(taskId & "終了しました。")
	End If
	
End Sub

' Shell() 関数で非同期処理を実行する。タスクIDを取得する。
Public Function ExecShell(cmd as String) As Long
    ExecShell = Shell("C:\windows\system32\cmd.exe /c" & cmd, vbNormalFocus)

End Function

'実行中プログラム監視
Public Sub Wait(taskId As Long)
    ' 実行中のプログラムのハンドルを取得する。
    Dim hdl As Long
    hdl = OpenProcess(&H400&, True, taskId)

    ' プログラムのハンドルを監視して、Codeが0になるまで待機する。
    eCode As Long
    eCode = 0
    Do
        Call GetExitCodeProcess(hdl, eCode)
        DoEvents
    Loop While eCode = &H103

    Call CloseHandle(hdl)

End Sub

'実行中プログラムの状況確認
Public Function IsActive(taskId As Long) As Boolean
    Dim hdl As Long
    hdl = OpenProcess(&H400&, True, taskId)

    ' プログラムのハンドルを監視して、Codeが0になるまで待機する。
    Dim eCode As Long
    Call GetExitCodeProcess(hdl, eCode)
    If eCode = &H103 Then
    	IsActive = True
    Else
    	IsActive = False
    End If

    Call CloseHandle(hdl)

End Function