Re: Windows process
by bpphillips (Friar) on Sep 16, 2004 at 13:52 UTC
|
Usually you would handle this type of "single instance" issue with some sort of file locking mechanism. In doing a quick search on CPAN you might consider using Win32::Mutex or File::Flock.
I haven't used either of those as the company I work with has our own in-house module to handle mutex situations.
Here's a quick example (untested):
use File::Flock;
# the following croaks if it fails
my $lock = new File::Flock("C:\lock_file");
# do whatever here
# this will happen automatically once $lock
# goes out of scope but it doesn't hurt to do
# it explicitly once you're done with the lock
$lock->unlock();
| [reply] [Watch: Dir/Any] [d/l] |
Re: Windows process
by bsdz (Friar) on Sep 16, 2004 at 15:09 UTC
|
This will return a list of running process ids, names and their command lines on Windows XP and above. For Windows 2000 and lower you will need to find a workaround.
use Win32::OLE;
my $wmi = Win32::OLE->GetObject("winmgmts:")
or die "wmi connect failed!";
my $P = $wmi->ExecQuery("SELECT * FROM Win32_Process")
or die "Win32_Process connect failed!";
foreach my $p (in $P) {
print join(',' , $p->ProcessId, $p->Name, $p->CommandLine)."\n";
}
For more info on WMI and Win32_Process see Microsoft's documentaion | [reply] [Watch: Dir/Any] [d/l] |
|
| [reply] [Watch: Dir/Any] |
Re: Windows process
by traveler (Parson) on Sep 16, 2004 at 15:02 UTC
|
Win32::Mutex sounds like a simple and appropriate solution. If you end up using File::Flock, beware of the case where a file exists after an abnormal termination of a process. That is, where there is a file and no process.
Yet another approach is to use Tie::Registry to store the process id of the process in the Registry when it starts. The pseudo code would be something like this:
if the key is in the registry and
that process (value of the key) is still running, exit
put the processid of the current process in the registry,
creating the key if necessary
"rest of program"
HTH, --traveler | [reply] [Watch: Dir/Any] [d/l] |
|
Re: flock. But if the process dies, surely the lock is released from the file, so it doesn't matter if the lock file is left behind
| [reply] [Watch: Dir/Any] |
Re: Windows process
by Tii (Monk) on Sep 16, 2004 at 13:58 UTC
|
File locking definitely sounds like the way to go. When you're starting the new process, it can check if a particular file has been locked. If it has, the process knows that there is already a process running. If it hasn't, this process can lock it to indicate to any subsequent processes that there is already a process running. Should be pretty simple.
HTH.
| [reply] [Watch: Dir/Any] |
|
Merlyn has a neat trick whereby he places a lock on the script itself in a begin block. If the lock already exists at startup, the script is already being run. I forget the details, but a super search should find it.
Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
"Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
| [reply] [Watch: Dir/Any] [d/l] |
|
# This is a trick used to prevent concurrent applications
# from running, but that will work WITHOUT needing pid
# or lock files, and so is kill -9 or power failure safe.
# To work it needs a __DATA__ section to be defined at
# the end of the file.
use Fcntl 'LOCK_EX', 'LOCK_NB';
unless ( flock DATA, LOCK_EX | LOCK_NB ) {
# An existing instance of this application is already running
print STDERR "Program is already running\n";
exit(0);
}
__DATA__
Used as a lock to prevent concurrent execution.
Do not remove this data section.
Of course, I'm not sure how well it would work on Win32, but I'm sure there's an equivalent | [reply] [Watch: Dir/Any] [d/l] |
|
Re: Windows process
by vladdrak (Monk) on Sep 17, 2004 at 00:20 UTC
|
You can use the tlist.exe executable from the Resource Kit to get the 'CmdLine' for a running process. You need to pass tlist the pid as an arg and then parse the output, as you'll also get all the loaded modules and memory info. Another option would be to write the PID of the process out to a file and then check the file. As bsdz mentioned, you can also get the CmdLine param from WMI, on XP/2003. Tlist will work on NT4+.
| [reply] [Watch: Dir/Any] |