As it was an interesting challenge, here is an example of how to do it.

This takes Rads method a little further, to cater for the wrinkles I've talked about in the previous post.

The process finds all the active NTDVM process headers, and then identifies all the threads in the processes.

It then starts the Win16 application, and checks for all the threads again, recording any new ones.

Finally, it monitors the "new" threads, and exits with a message when one of them closes.

  • If you need to keep an application running, just use this and restart when it closes.
  • If you need to check whether the application is already running, then use this technique to record the thread details in the registry or an ini file after you start the application.
    When you next try to start the application, use the saved settings to check whether the process is still running or not.


Code:
Break ON

$=SetOption("Explicit","ON")
$=SetOption("WrapAtEOL","ON")
$=SetOption("ASCII","ON")

Dim $sExePath
Dim $aiExistThreads, $aiNewThreads
Dim $iThread
Dim $sThreadList
Dim $iCheckInterval

Global $oWMIService

$iCheckInterval=3 ; How often do we check if application is still active
$sExePath="C:\Program Files\JETFRM41\JFDESIGN.EXE" ; What is the application to run?

$oWMIService = GetObject("winmgmts:\\.\root\cimv2")
If @ERROR "Cannot access WMI sevrice, error is " @ERROR ": " @SERROR ? Exit @ERROR EndIf

$aiExistThreads=GetThreadHandles(GetProcessList('Where Caption="NTVDM.EXE"'))
Run $sExePath
Sleep 1
$aiNewThreads=GetThreadHandles(GetProcessList('Where Caption="NTVDM.EXE"'))

$sThreadList=""
For Each $iThread in $aiNewThreads
"Checking "+$iThread+": "
If $iThread
If (AScan($aiExistThreads,$iThread)+1)
"Existing thread" ?
Else
"New thread" ?
$sThreadList=$sThreadList+","+$iThread
EndIf
EndIf
Next

If $sThreadList
Dim $aiThreads
Dim $colThread, $oThread
Dim $i, $bThreadRunning
$sThreadList=SubStr($sThreadList,2)
$aiThreads=Split($sThreadList,",")
? "Monitoring application threads: "+$sThreadList ?
While Not KBHit()
For Each $iThread In $aiThreads
$bThreadRunning=0
@TIME+" Checking "+$iThread+" is still running "
$colThread=$oWMIService.ExecQuery('Select Handle from Win32_Thread Where Handle="'+$iThread+'"',,48)
For Each $oThread In $colThread $bThreadRunning=1 Next
If $bThreadRunning
"OK" ?
Else
"Stopped" ?
? "*** APPLICATION HAS PROBABLY CLOSED ***" ?
Exit 0
EndIf
Next
Sleep $iCheckInterval
Loop
Get $
Else
"**ERROR** Application failed to start, was already started (single instance only) or was too slow!" ?
EndIf

Exit 0

Function GetProcessList(Optional $sWhereClause)
Dim $colProcess,$oProcess,$sProcessList
$colProcess=$oWMIService.ExecQuery('Select Handle from Win32_Process '+$sWhereClause,,48)
For Each $oProcess In $colProcess
$sProcessList=$sProcessList+"|"+$oProcess.Handle
Next
$GetProcessList=Split(SubStr($sProcessList,2),"|")
EndFunction

Function GetThreadHandles($aiPidList)
Dim $iPid
Dim $colThread, $oThread, $sThreadList

For Each $iPid In $aiPidList
If $iPid
"Checking for threads in process "+$iPid ?
$colThread=$oWMIService.ExecQuery('Select Handle from Win32_Thread Where ProcessHandle="'+$iPid+'"',,48)
For Each $oThread in $colThread
" Found thread "+$oThread.Handle ?
$sThreadList=$sThreadList+"|"+$oThread.Handle
Next
EndIf
Next
$GetThreadHandles=Split(SubStr($sThreadList,2),"|")
EndFunction