Richie19Rich77
(Seasoned Scripter)
2004-05-18 02:52 PM
Child PID

Hi Everyone

I need to write a little script that will check if the application is alreasy running, if not then run it.

Well seems really easy, but when running the application it opens up a process name called "ntvdm.exe", and then 4 child PIDs under the parent PID.

Then when I clode down the application 3 of the child PIDs clode down but it leaves 1 child PID called WOWEXEC.EXE.

So what I am really asking is that I cannot use EnumProcess, to check for the PID number as it looks at the parent pid and not a child pid.

So do you think there is another other way.

Thanks


LonkeroAdministrator
(KiX Master Guru)
2004-05-18 04:26 PM
Re: Child PID

borrowing from wintaskspro library:
Quote:

wowexec - wowexec.exe - Process Information
Process File: wowexec or wowexec.exe
Process Name: Windows On Windows Execution Process
Description: Windows On Windows Execution Support Process that provides support for 16-bit Windows applications together with ntvdm.exe. The service is started by NTVDM, which starts every time you run a 16-bit program.
Company: Microsoft Corp.
System Process: Yes
Security Risk ( Virus/Trojan/Worm/Adware/Spyware ): No
Common Errors: N/A





now I must ask, why you need to get rid of this?
it's not that huge so it can be left running just fine.
not sure do all of the 16-bit instances share the same process or do they start their own, but...
this is part of the OS, so I think it's perfectly fine to leave it there.


Richie19Rich77
(Seasoned Scripter)
2004-05-18 05:02 PM
Re: Child PID

Hi Everyone

Thanks for replying, I don;t really care about wowexec.exe but another Child PID called ASCShell.exe, but when using UDF EnumProcess, it only shows Parent objects.

This is because it uses WMI (Select * from Win32_Process).

Any other ideas.

Thanks


Richie19Rich77
(Seasoned Scripter)
2004-05-18 06:29 PM
Re: Child PID

Does that make sence ??

Kdyer
(KiX Supporter)
2004-05-18 09:34 PM
Re: Child PID

What about -

PsInfo

PsKill

Kent


Richie19Rich77
(Seasoned Scripter)
2004-05-18 11:52 PM
Re: Child PID

Nope PSKill shows only parent pids, and psinfo does not show info regarding processes.

Rich


LonkeroAdministrator
(KiX Master Guru)
2004-05-19 12:03 AM
Re: Child PID

so, this is not working:
shell "kill -f ASCShell.exe"

I know it works for kix (without logging me off )


Richie19Rich77
(Seasoned Scripter)
2004-05-19 12:17 PM
Re: Child PID

Thanks, but I am not trying to kill the process, just check that it is there.

AscShell.exe is a child process of NTDVM.exe, the problem is when the app closes down, it leaves the parent process in place, and only ascshell.exe closes.

So I cannot do a check on the parent because it will always be there.

Thanks


Glenn BarnasAdministrator
(KiX Supporter)
2004-05-19 02:08 PM
Re: Child PID

Try:
Code:

Shell('%ComSpec% /C pslist.exe | %SystemRoot%\System32\Find.exe /I "My_Proc" >NUL:')
If Not @ERROR
; process running
Else
; process not running
EndIf



Note the location of single vs double quotes. Replace "My_Proc" with your process name, or a variable. If using NoVarsInStrings, it would be "' + $Var + '" to preserve the quotes.

Glenn


Richie19Rich77
(Seasoned Scripter)
2004-05-19 04:04 PM
Re: Child PID

PSList only shows parent processes.

Thanks Anyhow.

Rich


Richard H.Administrator
(KiX Supporter)
2004-05-19 04:12 PM
Re: Child PID

You can enumerate the threads from "Win32_Thread" and link back to the parent process using ProcessHandle - Hurrah

Unfortunately the "Name" and "Caption" fields are empty, so it is not possible to identify the thread - Boo


Richie19Rich77
(Seasoned Scripter)
2004-05-20 12:12 AM
Re: Child PID

I am glad in a funny way that no one has solved this problem.

Thanks guys for your help, but this problem may have to be left unsolved.

Thanks


Radimus
(KiX Supporter)
2004-05-20 02:13 AM
Re: Child PID

how about this as an endaround...

enum all PIDs before starting the install/app and dump into an array
start the app
enum the PIDs again discarding the ones that exist in the first array

then you can discard the ones with processnames not what you are looking for


it is a definite kludge.. but you may get what you are looking for


AllenAdministrator
(KiX Supporter)
2004-05-20 05:10 AM
Re: Child PID

Have your tried PrcView?
There is a windows version and a command line version.

Quote:


Displays complete task tree – parent/child relationships for all processes in the system





Richie19Rich77
(Seasoned Scripter)
2004-05-20 12:28 PM
Re: Child PID

Thanks Al will look at that.

Rad. The problem with this Pharmacy Application is that when you start your computer, no process is open for the App.

But when you start the app for the very 1st time, One Parent process opens and 3 Child Processes opens.

When you close down the app, only one of the child processess closes.

Thanks


LonkeroAdministrator
(KiX Master Guru)
2004-05-20 01:36 PM
Re: Child PID

eh?
why an problem?
I saw no problem with rads suggestion about this.


Richard H.Administrator
(KiX Supporter)
2004-05-20 02:20 PM
Re: Child PID

Ok. An explanation.

When you start old (16 bit) apps the operating system creates a safe environment to execute them in, and a process to do the thunking. These are your NTVDM and WOWEXEC threads.

Your application is started as another thread within the NTVDM process.

When you start another 16 bit app, it uses the existing NTVDM process (and WOWEXEC) to save memory.

When you close your 16 bit app, the OS may decide to leave the NTVDM process hanging around in case you start another one.

Now, I can think of a way of enhancing Rads suggestion to make it work for you.

Before I start on something that will take a while to put together, why don't you take a step back and explain exacly what it is you are trying to do, and why?

It may be that there is a far simpler way of doing it - looking for window titles, open files/shares etc.


Richard H.Administrator
(KiX Supporter)
2004-05-20 05:38 PM
Re: Child PID

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