Killing a Process started with Kernel.system

Hi!

I know, this question was asked a dozen times, but I can't believe that Ruby does not offer a suitable solution. I therefore write this posting more in the spirit of an urgent feature request.

Under Windows, I want to start an external program and kill it on exitting my Ruby script.

begin
   $t = Thread.new { system("everlasting") }
   ...
ensure
   $t.kill
end

does not stop the everlasting program, it stops $t, not its child processes. Such a command is urgently needed!

Yukihiro Matsumoto writes in <1052988371.738185.28868.nullmailer@picachu.netlab.jp>:

If you want to kill child processes when the thread is down,

  th = Thread.new{
     Thread.current[:children] =
     begin
       ... add child processes to Thread.current[:children]
     ensure
       Process.kill("TERM", *Thread.current[:children])
     end
  }

but I think I can't get the PID of a system call either.

I would be glad if such a feature could be implemented. (Or, of course, if anyone can tell me suitable solution.)

Martin

Under Windows, I want to start an external program and kill it on
exitting my Ruby script.

begin
   $t = Thread.new { system("everlasting") }
   ...
ensure
   $t.kill
end

does not stop the everlasting program, it stops $t, not its child
processes. Such a command is urgently needed!

Yukihiro Matsumoto writes in
<1052988371.738185.28868.nullmailer@picachu.netlab.jp>:
> If you want to kill child processes when the thread is down,
>
> th = Thread.new{
> Thread.current[:children] =
> begin
> ... add child processes to Thread.current[:children]
> ensure
> Process.kill("TERM", *Thread.current[:children])
> end
> }
but I think I can't get the PID of a system call either.

I would be glad if such a feature could be implemented. (Or, of course,
if anyone can tell me suitable solution.)

I'm guessing the problem is your "everlasting" program
spawns itself in the manner of rubyw.exe, where it
does sort of the windows equivalent of daemonizing
itself. So your system("everlasting") call returns
immediately, and your "everlasting.exe" is launching
as a separate process, for which you have no way (that
I know of) of obtaining the PID.

Maybe a windows guru can help. I'm doubtful this is
a behavior ruby has any control over. If I understand
correctly, you may be up against a fundamental problem
with Windows' way of launching non-console applications.
(I guess there must be some way to solve it, if one
were to write an extension, since certainly the Visual
Studio debugger is able to launch non-console
applications but obtain their PID's.)

Sorry I can't be of more help,

Regards,

Bill

···

From: "Martin aus Chemnitz" <MartinAusChemnitz@gmx.net>

Hi,

At Tue, 24 May 2005 14:40:17 +0900,
Martin aus Chemnitz wrote in [ruby-talk:143491]:

Yukihiro Matsumoto writes in
<1052988371.738185.28868.nullmailer@picachu.netlab.jp>:
> If you want to kill child processes when the thread is down,
>
> th = Thread.new{
> Thread.current[:children] =
> begin
> ... add child processes to Thread.current[:children]
> ensure
> Process.kill("TERM", *Thread.current[:children])
> end
> }
but I think I can't get the PID of a system call either.

Fundamentally, since Kernel.system doesn't finish until the child
process exits, so PID can not be available.

I would be glad if such a feature could be implemented. (Or, of course,
if anyone can tell me suitable solution.)

In 1.9, Kernel.spawn (or Process.spawn) does it.

···

--
Nobu Nakada

Hi,

At Tue, 24 May 2005 14:40:17 +0900,
Martin aus Chemnitz wrote in [ruby-talk:143491]:

Yukihiro Matsumoto writes in
<1052988371.738185.28868.nullmailer@picachu.netlab.jp>:
> If you want to kill child processes when the thread is down,
>
> th = Thread.new{
> Thread.current[:children] =
> begin
> ... add child processes to Thread.current[:children]
> ensure
> Process.kill("TERM", *Thread.current[:children])
> end
> }
but I think I can't get the PID of a system call either.

Fundamentally, since Kernel.system doesn't finish until the child
process exits, so PID can not be available.

I would be glad if such a feature could be implemented. (Or, of course,
if anyone can tell me suitable solution.)

In 1.9, Kernel.spawn (or Process.spawn) does it.

···

--
Nobu Nakada

Here's a way to kill any process using Win32OLE:

require 'win32ole'

class WIN32OLE
     def to_a
         a = ; self.each{ |p| a<<p }; a
     end
end

# Find the process for the player
mgmt = WIN32OLE.connect('winmgmts:\\\\.')
process = mgmt.InstancesOf("win32_process").to_a.find{ |proc| proc.name =~ /myapp.exe/ }
process.Terminate

···

On May 23, 2005, at 11:40 PM, Martin aus Chemnitz wrote:

Under Windows, I want to start an external program and kill it on exitting my Ruby script.

begin
  $t = Thread.new { system("everlasting") }
  ...
ensure
  $t.kill
end

does not stop the everlasting program, it stops $t, not its child processes. Such a command is urgently needed!

so no way by pid?

-a

···

On Tue, 24 May 2005, Gavin Kistner wrote:

On May 23, 2005, at 11:40 PM, Martin aus Chemnitz wrote:

Under Windows, I want to start an external program and kill it on
exitting my Ruby script.

begin
  $t = Thread.new { system("everlasting") }
  ...
ensure
  $t.kill
end

does not stop the everlasting program, it stops $t, not its child
processes. Such a command is urgently needed!

Here's a way to kill any process using Win32OLE:

require 'win32ole'

class WIN32OLE
    def to_a
        a = ; self.each{ |p| a<<p }; a
    end
end

# Find the process for the player
mgmt = WIN32OLE.connect('winmgmts:\\\\.')
process = mgmt.InstancesOf("win32_process").to_a.find{ |proc|
proc.name =~ /myapp.exe/ }
process.Terminate

--

email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
My religion is very simple. My religion is kindness.
--Tenzin Gyatso

===============================================================================