Option Explicit
Const PROCESS_ALL_ACCESS As Long = &H1F0FFF
Const STILL_ACTIVE As Long = &H103
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private appFocus As Long, appWaitInSecond As Long
Public Property Let SetWaitInSecond(second As Long)
appWaitInSecond = IIf(second > 0, second, 0)
End Property
Public Property Let SetFocus(focus As Long)
If focus >= 0 And focus < 7 Then
appFocus = focus \ 1
Else
appFocus = vbNormalFocus
End If
End Property
Function Execute(fname As String) As Boolean
Dim lExitCode As Long, hdlProg As Long, progID As Long, lastTime As Variant
progID = Shell(fname, appFocus)
hdlProg = OpenProcess(PROCESS_ALL_ACCESS, False, progID)
lastTime = Now + TimeValue("0:00:" & appWaitInSecond)
Do
If Now > lastTime And appWaitInSecond <> 0 Then
MsgBox "Превышено время ожидания", vbCritical
CloseHandle (hdlProg)
Execute = False
Exit Function
End If
DoEvents
GetExitCodeProcess hdlProg, lExitCode
Loop While lExitCode = STILL_ACTIVE
CloseHandle (hdlProg)
Execute = True
End Function
Оформите как класс и будет вам счастье. Процедурка ждет завершения работы любого приложения, которое вызвали через shell