davidj has asked for the wisdom of the Perl Monks concerning the following question:
My Fellow Monks,
(I know you will feel my pain)
Woe is me, for I have been tasked with using Perl to ensure another Perl program is running on a win2K machine. I offered to forego my internet privileges for a month if they would let the cup pass, but the Powers-That-Be declined :-)
Here is my situation:
I have a little script that launches on Windows startup. All it does is tail an application log every 5 minutes and then send an email to a particular user if certain messages appear in the log. Very plain, very simple. When I check the Windows machine, I discover that, for some reason, the script is no longer running. I have an error logging facility for it, but nothing in it indicates why it has died. The application whose log it is tailing is still running and everyone who has access to the machine swears they are not killing it. So I have been asked to write something that will check periodically to see if the script has died, and if so, kick it off again. (The Powers-That-Be were not interested in hearing about what would need to be done if the script that checks the script dies also).
So, finally, to my question:
Do any of you know of a way to get a list of all running programs on a Windows machine either my name or process Id? I figure this is the best way to determine if a program is running. I have examined the Win32 modules, but I cannot find anything. If it's in there, I certainly am missing it.
Or, if any of you have any other suggestions for how I might accomplish this task, I am most definately all ears.
as always, your input is greatly appreciated.
davidj
Re: Check if a process is running on Windows
by arden (Curate) on Jun 13, 2004 at 21:46 UTC
|
From the description for Proc::Background, "This is a generic interface for placing processes in the background on both Unix and Win32 platforms. This module lets you start, kill, wait on, retrieve exit values, and see if background processes still exist."
- - arden.
update: While you're there, Win32::Process::Info has the @info = $pi->GetProcInfo (); method which should return a host of information on every process running (except the idle and system processes) including the executable path and name. | [reply] [Watch: Dir/Any] [d/l] |
|
I guess looking hard doesn't mean much if you're looking in the wrong place, huh? :-)
Thanks a bunch. I'll check it out.
davidj
| [reply] [Watch: Dir/Any] |
Re: Check if a process is running on Windows
by Caron (Friar) on Jun 13, 2004 at 21:44 UTC
|
One solution comes to mind.
Write a script that launches the critical script, and does something when it is no longer running.
#!/usr/bin/perl -w
use strict;
print "script started!\n";
my $result = system "critical.pl";
# if it comes here, then the script has died.
print "critical.pl is no longer running. (Exit code $result)\n";
#perhaps add code to send a mail to your address
| [reply] [Watch: Dir/Any] [d/l] |
Re: Check if a process is running on Windows
by bibo (Pilgrim) on Jun 14, 2004 at 01:41 UTC
|
Umm, this is pointed in a slightly different direction....
How about having the original script write it's PID at start to a file, say foo.run? your metascript could grab that PID and then query the OS if this particular PID is alive and kicking.... I have also written programs that update the run file every N minutes, as a keep-alive indicator. Then at least you have some idea when it died, and can start determining WHY it died. Good luck, I know how ugly and hurtful the Win32 world can be <grin> | [reply] [Watch: Dir/Any] |
Re: Check if a process is running on Windows
by BrowserUk (Patriarch) on Jun 13, 2004 at 22:59 UTC
|
:redo
@notepad & goto redo
Just substitute your program path/name for notepad.
Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
| [reply] [Watch: Dir/Any] [d/l] |
|
i would have thought that it would be worthwhile to investigate why the tail script dies. had a situation at work recently where my scripts only processed half the file and we didn't notice until later. it took a bit of head scratching to find that the file being processed had an eof character in it. this may not be the answer but, tail will exit if it sees eof in input stream.
| [reply] [Watch: Dir/Any] |
Re: Check if a process is running on Windows
by mhi (Friar) on Jun 14, 2004 at 09:01 UTC
|
Granted, this is not particularly a perl answer... :-)
You may be happier installing cygwin on that box to have a Unix-like environment in which to run your scripts. With a simple ps -efW you'll see not only the cygwin processes, but also the Windows ones. You might also want to run your checker (and perhaps the original tail-and-mail script) from cygwin's cron utility.
Also, a common way to check whether something is still running (actually running and not stuck somewhere) is to have it do something external (like touch a certain file or write into a log - a generalization of what bibo mentioned above) every once in a while and checking periodically whether this action has been executed recently enough. That may be better than simply checking for the existence of a process.
Have fun! | [reply] [Watch: Dir/Any] [d/l] |
Re: Check if a process is running on Windows
by AJRod (Scribe) on Jun 14, 2004 at 06:57 UTC
|
Are you running the script/program as a service? I have recently stumbled upon this article and thought it might help.
(I hope you will pardon this response if it appears naive.)
________________________
Please forgive me for earlier sending you the above link to an article which I only later on discovered to be available only to subscribers of the website. Anyway, for whatever it was worth, the basic idea at least was there. Hope that helps.
| [reply] [Watch: Dir/Any] |
Re: Check if a process is running on Windows
by paulbort (Hermit) on Jun 14, 2004 at 18:51 UTC
|
| [reply] [Watch: Dir/Any] |
Re: Check if a process is running on Windows
by mrpeabody (Friar) on Jun 14, 2004 at 18:36 UTC
|
PsList 1.22 - Process Information Lister
Copyright (C) 1999-2002 Mark Russinovich
Sysinternals - www.sysinternals.com
Usage: pslist.exe [-d][-m][-x][-t][-s [n] [-r n] [\\computer [-u usern
+ame][-p password][name|pid]
-d Show thread detail.
-m Show memory detail.
-x Show processes, memory information and threads.
-t Show process tree.
-s [n] Run in task-manager mode, for optional seconds specifie
+d.
Press Escape to abort.
-r n Task-manager mode refresh rate in seconds (default is 1
+).
\\computer Specifies remote computer.
-u Optional user name for remote login.
-p Optional password for remote login. If you don't presen
+t
on the command line pslist will prompt you for it if ne
+cessary.
name Show information about specified process.
pid Show information about specified process.
(OT, would it kill CODE tags to wrap at 80 columns instead of 70?) | [reply] [Watch: Dir/Any] [d/l] |
Re: Check if a process is running on Windows
by pgor (Beadle) on Jun 14, 2004 at 21:46 UTC
|
use Win32::PerfLib;
sub getProcessList {
# this code is copied almost verbatim from the Win32::PerfLib docs
# it's really convoluted and confusing, but it works for finding
# the pid and name of running processes
my @proc_objs = ();
my %counter = ();
Win32::PerfLib::GetCounterNames( '', \%counter );
my %r_counter = map { $counter{$_} => $_ } keys %counter;
# retrieve the id for process object
my $process_obj = $r_counter{ Process };
# retrieve the id for the process ID counter
my $process_id = $r_counter{ 'ID Process' };
# create connection to $server
my $perflib = new Win32::PerfLib( '' );
my $proc_ref = {};
# get the performance data for the process object
$perflib->GetObjectList( $process_obj, $proc_ref );
$perflib->Close();
my $instance_ref = $proc_ref->{ Objects }->{ $process_obj }->{ Insta
+nces };
foreach my $p ( sort keys %{$instance_ref} ) {
my $counter_ref = $instance_ref->{ $p }->{ Counters };
foreach my $i ( sort { $a <=> $b } keys %{$counter_ref} ) {
if ( $counter_ref->{ $i }->{ CounterNameTitleIndex } == $process
+_id ) {
push @proc_objs, { id => $counter_ref->{ $i }->{ Counter },
name => $instance_ref->{ $p }->{ Name },
};
}
}
}
return @proc_objs;
}
| [reply] [Watch: Dir/Any] [d/l] |
|
|