I think, this will do the job.
___
Option Explicit
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds 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
Const SYNCHRONIZE = &H100000
Const PROCESS_QUERY_INFORMATION = &H400
Const INFINITE = -1&
Private Sub Form_Load()
Dim ProcessId As Long, hProcess As Long, ExitCode As Long
ProcessId = Shell("notepad.exe", vbNormalFocus)
hProcess = OpenProcess(SYNCHRONIZE Or PROCESS_QUERY_INFORMATION, 0, ProcessId)
'Stop here until the program finishes
'otherwise GetExitCodeProcess will fail.
WaitForSingleObject hProcess, INFINITE
GetExitCodeProcess hProcess, ExitCode
CloseHandle hProcess
MsgBox "Exit code = " & ExitCode
End
End Sub
___
Microsoft say that the SYNCHRONIZE flag is specified with OpenProcess function to use the return handle with wait functions(WaitForSingleObject). This flags works only with Windows NT systems. So if you want to run this code on Windows 98 then you must execute the program with CreateProcess API to obtain the process handle directly. This handle will be used with both the functions, i.e. WaitForSingleObject and GetExitCodeProcess.