Try WaitForSingleObject api. I used it in a batch processing app, and it has never failed.

Code:
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Public Const WAIT_TIMEOUT = &H102&

'a little piece of code
    retVal = WaitForSingleObject(ProcessHandle, 0)
    If retVal <> WAIT_TIMEOUT Then
        ' app is finished
        ' close the handle of the process
        Call CloseHandle(ProcessHandle)
    End If