Board index » Visual Studio » killing child processes

killing child processes

Visual Studio369
I'm using a vbscript to



Set WshShell = CreateObject("WScript.Shell")

Set oExec = WshShell.Exec("program.exe")



Sometimes this program hangs, and I'd like it to timeout and be

killed. I can do this with:



oExec.Terminate()



But "program.exe" spawns a child process which does not get killed.



Is there a way to track the child processes spawned and/or kill them?

I know the name of the process spawned, but there may be more than

one parent/child pair running simultaneously, so I'm wary of the

solutions I've quoted below.

Any help?



<qoute>

From: Michael Harris (Please.Respond@To.NewsGroup)

Subject: Re: "bWaitOnReturn" option for WshShell.Run method

Newsgroups: microsoft.public.scripting.wsh

Date: 2000/11/27



"...Is there a way of tracking which processes are spawned by other

processes.

..."



If you know that foo.exe will spawn an instance of bar.exe, you

*could* use

WMI it track the PIDs

(Process IDs) of instances of bar.exe. For example, before executing

foo.exe,

record the PIDs (if

any) of bar.exe instances. Execute foo.exe and recheck the PIDs for

bar.exe

instances. The one

that is new is for the new instance of bar.exe spawned by foo.exe.

There

might even be a more

direct way using WMI notification events but that would take a lot

more time

to research ;-)...



I don't know if there is a generic technique available to script

clients to

track the child

processes of an arbitrary parent process. If there is one it would

probably

involve WMI...



--

Michael Harris

Microsoft.MVP.Scripting

--

mikhar@mvps.org

Please do not email questions - post them to the newsgroup instead.

--



"Andrew Britton" <andrewjbritton@hotmail.com>wrote in message

Quote
As a follow on, taking up Michael's point, what, if anything, can be done if

the process DOES spawn another process then self terminate. Is there a way

of tracking which processes are spawned by other processes. If this is the

case, it should be possible to write code which watches an initial process,

and waits until both it, and any child processes (and children thereof) have

also terminated! The more I think about it, the more it scares me!



This is not just an academic question, as I have a genuine use for this.



Opinions/answers please!





</qoute>







Janak Sanariya wrote:



Quote
I have script that kills a process but I need to modify it so that it also

kills the any child processes....is there any way to do this?

-J



'Purpose To kill a process given it Process ID(PID).

'Arugments There is only one argument, the process ID of

' the process that needs to be killed



set WMI = getobject("winmgmts:")



sQuery = "select * from win32_process " _

& "where ProcessID=" & Wscript.Arguments(0)

set processes = WMI.execquery(sQuery)



For Each Process in processes

process.terminate

next


-
 

Re:killing child processes

Bill Comisky wrote:

Quote
I'm using a vbscript to



Set WshShell = CreateObject("WScript.Shell")

Set oExec = WshShell.Exec("program.exe")



Sometimes this program hangs, and I'd like it to timeout and be

killed. I can do this with:



oExec.Terminate()



But "program.exe" spawns a child process which does not get killed.



Is there a way to track the child processes spawned and/or kill them?

I know the name of the process spawned, but there may be more than

one parent/child pair running simultaneously, so I'm wary of the

solutions I've quoted below.

Any help?





Instead of:



oExec.Terminate()



Do this:



pid = oExec.ProcessID



server = "."



set wmi = getobject("winmgmts://" & server)



set rootProcess = _

wmi.get("win32_process.handle=" & pid)



KillProcessTree rootProcess



sub KillProcessTree(process)



' wscript.echo _

' process.name, _

' process.handle, _

' "is a child of", process.parentprocessid



wql = "select * from win32_process " _

& "where ParentProcessID=" & process.handle



set results = wmi.execquery(wql)



for each childProcess in results

KillProcessTree childProcess

next



process.terminate



end sub







Quote


<qoute>

From: Michael Harris (Please.Respond@To.NewsGroup)

Subject: Re: "bWaitOnReturn" option for WshShell.Run method

Newsgroups: microsoft.public.scripting.wsh

Date: 2000/11/27



"...Is there a way of tracking which processes are spawned by other

processes.

..."



If you know that foo.exe will spawn an instance of bar.exe, you

*could* use

WMI it track the PIDs

(Process IDs) of instances of bar.exe. For example, before executing

foo.exe,

record the PIDs (if

any) of bar.exe instances. Execute foo.exe and recheck the PIDs for

bar.exe

instances. The one

that is new is for the new instance of bar.exe spawned by foo.exe.

There

might even be a more

direct way using WMI notification events but that would take a lot

more time

to research ;-)...



I don't know if there is a generic technique available to script

clients to

track the child

processes of an arbitrary parent process. If there is one it would

probably

involve WMI...



--

Michael Harris

Microsoft.MVP.Scripting

--

mikhar@mvps.org

Please do not email questions - post them to the newsgroup instead.



"Andrew Britton" <andrewjbritton@hotmail.com>wrote in message

news:#gOTqb#VAHA.243@cppssbbsa04...

>As a follow on, taking up Michael's point, what, if anything, can be

>done if the process DOES spawn another process then self terminate.

>Is there a way of tracking which processes are spawned by other

>processes. If this is the case, it should be possible to write code

>which watches an initial process, and waits until both it, and any

>child processes (and children thereof) have also terminated! The

>more I think about it, the more it scares me!

>

>This is not just an academic question, as I have a genuine use for

>this.

>

>Opinions/answers please!

>



</qoute>







Janak Sanariya wrote:



>I have script that kills a process but I need to modify it so that

>it also kills the any child processes....is there any way to do this?

>-J

>

>'Purpose To kill a process given it Process ID(PID).

>'Arugments There is only one argument, the process ID of

>' the process that needs to be killed

>

>set WMI = getobject("winmgmts:")

>

>sQuery = "select * from win32_process " _

>& "where ProcessID=" & Wscript.Arguments(0)

>set processes = WMI.execquery(sQuery)

>

>For Each Process in processes

>process.terminate

>next



--

Michael Harris

Microsoft.MVP.Scripting



Windows 2000 Scripting Guide

Microsoft® Windows®2000 Scripting Guide

www.microsoft.com/technet/scriptcenter/scrguide/sagsas_overview.asp">www.microsoft.com/technet/scriptcenter/scrguide/sagsas_overview.asp



TechNet Script Center Sample Scripts

http://www.microsoft.com/downloads/release.asp?ReleaseID" rel="nofollow" target="_blank">www.microsoft.com/downloads/release.asp=38942



WSH 5.6 documentation download

http://www.microsoft.com/downloads/details.aspx?FamilyId" rel="nofollow" target="_blank">www.microsoft.com/downloads/details.aspx=01592C48-207D-4BE1-8A76-1C4099D7BBB9&displaylang=en



-

Re:killing child processes

Thanks for your reply.. I tried your solution, and it looks like I

made a bad assumption about the new processes being under the process

I started in the process tree. When your method didn't work, I tried

"End Process Tree" from the Windows Task Manager. That didn't kill

the subprocesses either. So I used your script to report the tree

given a PID, and ran it for the PIDs of the process I started and

those subprocesses I want to kill.



The process (let's call it program.exe) I start from the vbscript has

"explorer.exe" as the parent.



explorer.exe 816 is a child of 800

program.exe 784 is a child of 816

program.exe 984 is a child of 816



The process started from program.exe (let's call it subprogram.exe)

has "svchost.exe" as the parent, the complete tree looks like:



System 8 is a child of 0

SMSS.EXE 140 is a child of 8

CSRSS.EXE 164 is a child of 140

WINLOGON.EXE 184 is a child of 140

SERVICES.EXE 212 is a child of 184

svchost.exe 412 is a child of 212

subprogram.exe 904 is a child of 412

sub1.exe 1456 is a child of 904

sub2.exe 792 is a child of 1456

subprogram.exe 1628 is a child of 412

sub3.exe 1436 is a child of 1628



So my problem is how to identify which subprogram.exe trees to

associate with each instance of program.exe. Maybe there is some more

data from the process I can query?



Any other ideas would be greatly appreciated! I'm off to read up on

WMI since I'm new to all this stuff.



thanks,

bill



"Michael Harris \(MVP\)" <mikhar@mvps.org>wrote in message news:<ehNU6SNoDHA.2244@TK2MSFTNGP12.phx.gbl>...

Quote
Bill Comisky wrote:

<snip>



>Is there a way to track the child processes spawned and/or kill them?

>I know the name of the process spawned, but there may be more than

>one parent/child pair running simultaneously, so I'm wary of the

>solutions I've quoted below.

>Any help?





Instead of:



oExec.Terminate()



Do this:



pid = oExec.ProcessID



server = "."



set wmi = getobject("winmgmts://" & server)



set rootProcess = _

wmi.get("win32_process.handle=" & pid)



KillProcessTree rootProcess



sub KillProcessTree(process)



' wscript.echo _

' process.name, _

' process.handle, _

' "is a child of", process.parentprocessid



wql = "select * from win32_process " _

& "where ParentProcessID=" & process.handle



set results = wmi.execquery(wql)



for each childProcess in results

KillProcessTree childProcess

next



process.terminate



end sub

-