The new vbAccelerator Site - more VB and .NET Code and Controls
Source Code
3 Code Libraries Source Code &nbsp

NOTE: this code has been superceded by the version at the new site.


Shell an application and wait asynchronously for completion

Shell Test Application Picture

Download the ShellWait project files (11kb)

The downloadable sample requires the SSubTmr.DLL component because it includes my UpDown custom control. Make sure you have loaded and registered this before trying the ShelWait project. Alternatively, just copy the code below!

Surprisingly often it comes in handy to be able to shell another application and wait for it to complete. This sample shows what I think is the best way to do it. At least, this method has been totally reliable for me. Its better than some methods I have seen because the application isn't frozen whilst the shelled application runs. Therefore the display is kept refreshed and it doesn't look like the app has hung.
The method makes use of the Win32 OpenProcess method. Here is the code:

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Function timeGetTime Lib "winmm.dll" () As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Const STILL_ACTIVE = &H103
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

Public Function ShellAndWaitForTermination( _
&nbsp &nbsp &nbsp &nbsp sShell As String, _
&nbsp &nbsp &nbsp &nbsp Optional ByVal eWindowStyle As VBA.VbAppWinStyle = vbNormalFocus, _
&nbsp &nbsp &nbsp &nbsp Optional ByRef sError As String, _
&nbsp &nbsp &nbsp &nbsp Optional ByVal lTimeOut As Long = 2000000000 _
&nbsp &nbsp ) As Boolean
Dim hProcess As Long
Dim lR As Long
Dim lTimeStart As Long
Dim bSuccess As Boolean
&nbsp &nbsp
On Error GoTo ShellAndWaitForTerminationError
&nbsp &nbsp
&nbsp &nbsp ' This is v2 which is somewhat more reliable:
&nbsp &nbsp hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False, Shell(sShell, eWindowStyle))
&nbsp &nbsp If (hProcess = 0) Then
&nbsp &nbsp &nbsp &nbsp sError = "This program could not determine whether the process started. Please watch the program and check it completes."
&nbsp &nbsp &nbsp &nbsp ' Only fail if there is an error - this can happen when the program completes too quickly.
&nbsp &nbsp Else
&nbsp &nbsp &nbsp &nbsp bSuccess = True
&nbsp &nbsp &nbsp &nbsp lTimeStart = timeGetTime()
&nbsp &nbsp &nbsp &nbsp Do
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp ' Get the status of the process
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp GetExitCodeProcess hProcess, lR
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp ' Sleep during wait to ensure the other process gets
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp ' processor slice:
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp DoEvents: Sleep 100
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp If (timeGetTime() - lTimeStart > lTimeOut) Then
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp ' Too long!
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp sError = "The process has timed out."
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp lR = 0
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp bSuccess = False
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp End If
&nbsp &nbsp &nbsp &nbsp Loop While lR = STILL_ACTIVE
&nbsp &nbsp End If
&nbsp &nbsp ShellAndWaitForTermination = bSuccess
&nbsp &nbsp &nbsp &nbsp
&nbsp &nbsp Exit Function

&nbsp &nbsp sError = Err.Description
&nbsp &nbsp Exit Function
End Function

For more flexibility, you might want to replace the VB Shell call with a call to the ShellExecute API function instead. See my article Using ShellExecute from Visual Basic - start any document from its filename only for more details.

Back to top

Back to Source Code Overview


AboutContributeSend FeedbackPrivacy

Copyright 1998-1999, Steve McMahon ( All Rights Reserved.
Last updated: 15 June 1998