On Mon, Apr 8, 2013 at 4:41 PM, Jonathan Harris <jtnhar...@googlemail.com>wrote:
> Hi All > > I am using Strawberry Perl (latest release) on a Windows 2003 SP2 server > > I am trying to use a script to look at running processes, look for a > specific process, and kill that process if it is alive for more than 4 > minutes as this would mean that the process has hung > > When testing killing Notepad or Firefox, it works fine > In practice when trying to kill "ovntag or oprop" processes, it doesn't > > It uses the following to kill the process: > > Win32::Process::KillProcess ($pid, \$exitcode); > > So here's the question. > Is there a difference between killing a process that is alive and one that > has hung? > In theory a process is a process, right?! > But the hanging process does not die! > > Is there a better way to kill a process so that a hanging process will > actually die? > > Thanks in advance > > Jon > > ps - the script also records a log if the process is killed - this > required a cleanup sub as for some reason I haven't worked out yet, I > cannot created the entire log file name in one go! This is not of concern - > will look into it soon enough > pps - Disclaimer! I am a total perl noob and have no code training, so > sorry if the code is ugly and wasteful > > ________________ > > #!C:\strawberry\perl\bin\perl.exe > #process3.pl > > use warnings; > use strict; > use Win32::Process; > use Win32::Process::List; > use DateTime; > > my %list; > my ( $process, $process_name, $pid, $new_pid, $it_lives, $it_lives_name, > $dt, $log_file ); > > $log_file = "C:/process_logs/log_" || shift; > $dt = DateTime->now(time_zone => 'Europe/London'); > > first_check(); > if ($it_lives) { > kill_it(); > } > cleanup(); > > sub first_check { > $process = Win32::Process::List->new(); > %list = $process->GetProcesses(); > foreach $pid ( sort {$a <=> $b} keys %list ) { > $process_name = $list{$pid}; > print "$pid\t$process_name\n"; > ## next line for testing only ## > if ($process_name =~/^notepad/ || $process_name =~/^fire/) { > ##if ($process_name =~/^ovntag/ || $process_name =~/^oprop/) { > $it_lives = $pid; > $it_lives_name = $process_name; > sleep 240; > return $it_lives, $it_lives_name; > } > } > undef %list; > } > > sub kill_it { > $process = Win32::Process::List->new(); > %list = $process->GetProcesses(); > foreach $new_pid ( sort {$a <=> $b} keys %list ) { > $process_name = $list{$new_pid}; > print "$new_pid\t$process_name\n"; > if ($it_lives == $new_pid) { > my $exitcode; > Win32::Process::KillProcess ($new_pid, \$exitcode); > open (my $fh, ">", "$log_file") || die "$!"; > print $fh $dt, "\n\n$new_pid\t$process_name\n"; > print $fh "\n", $it_lives, "\t$it_lives_name Was Killed", "\n\n"; > close $fh; > } > } > undef %list; > } > > sub cleanup { > my $oldname = "C:/process_logs/log_"; > my $newname = $oldname . $dt->ymd('-') . 'T' . $dt->hms('-') . "\.txt"; > rename $oldname, $newname; > } > > Hi All I may have found a possible solution and wanted to share it As it seems that Win32::Process::KillProcess is having difficulties killing a hanging process, I thought that it would probably make sense to ask the system to do it directly So, in the sub 'kill_it', I have replaced the line Win32::Process::KillProcess ($new_pid, \$exitcode); with system 'Taskkill /PID ' . ($new_pid); I am using 'system' rather than 'exec' as it returns a success status; 'exec' is silent in this respect Will put this live and see if it really resolves the issue (it does work in testing on active processes) Hope this is helpful to someone! Jon