views:

992

answers:

4

Using Perl, how do I check if a particular Windows process is running or not? Basically, I want to start a process using 'exec', but I should do this only if it is not already running.

So how to know if a process with particular name is running or not? Is there any Perl module which provides this feature?

+3  A: 

You're probably looking for Proc::ProcessTable (assuming you're using Unix!). It gives you access to the list of processes, and you can query its fields to find the process with the name. There are related packages to allow you to get at individual processes, depending what you want to do.

Jeremy Smyth
+4  A: 

Take a look at the following example that uses the Win32::OLE module. It lets you search for running processes whose names match a given regular expression.

#! perl

use warnings;
use strict;

use Win32::OLE qw(in);

sub matching_processes {
  my($pattern) = @_;

  my $objWMI = Win32::OLE->GetObject('winmgmts://./root/cimv2');
  my $procs = $objWMI->InstancesOf('Win32_Process');

  my @hits;
  foreach my $p (in $procs) {
    push @hits => [ $p->Name, $p->ProcessID ]
      if $p->Name =~ /$pattern/;
  }

  wantarray ? @hits : \@hits;
}

print $_->[0], "\n" for matching_processes qr/^/;
Greg Bacon
+1  A: 

Maybe you don't have control over the second process, but if you do, a good way to do this is to have the process write its pid ($$) out to a file in a known location. Then you can read the file and see if that pid exists using kill($pid, 0).

ysth
If you do that make sure to empty/delete that file at the end of each run. If the PID's been re-issued you run the risk of killing an innocent program.
Anon
kill 0 just checks if the pid is running, but you're right; the file needs to be deleted on termination.
ysth
A: 

What you really want is a way to stop a process from running if it is already running (what if you have two different programs with the same name, or decide to name your program explorer.exe?) This works for me on Linux:

use Fcntl ':flock';

open SELF, '<', $0 or die 'I am already running...';
flock SELF, LOCK_EX | LOCK_NB  or exit;

In my testing that code does not want to be in any block.

(source)

Anon