这是用于检查Windows服务状态的脚本,如果它们处于停止状态,它将启动该服务。我能够获得服务状态,但无法启动服务。 请帮忙,让我知道我需要做什么。
#!/usr/local/bin/perl
use Win32::Service;
use strict;
sub checkService();
sub getDate();
sub getTime();
sub logEvent();
my @timeInfo = localtime(time);
my $serviceName = "TapiSrv";
my $currentDate = getDate();
my $currentTime = getTime();
my %status;
my %status_code = (1 => 'not running',
2 => 'start pending',
3 => 'stop pending',
4 => 'running',
5 => 'resume pending',
6 => 'pause pending',
7 => 'paused');
checkService();
########
# SUBS
########
sub checkService() {
my $startCounter = 0;
Win32::Service::GetStatus('', $serviceName, \%status);
if($status{"CurrentState"} eq '4') {
# Log the event
&logEvent("$currentTime: $serviceName is running\n");
} elsif($status{"CurrentState"} eq '1') {
Win32::Service::StartService('', $serviceName);
}
while($startCounter < 3) {
sleep(5);
Win32::Service::GetStatus('', $serviceName, \%status);
if($status{"CurrentState"} eq '2') {
$startCounter++;
} else {
$startCounter = 3;
}
}
if($startCounter == 3) {
&logEvent("$currentTime: Unable to start $serviceName in $startCounter attempts\n");
} else {
&logEvent("$currentTime: Started $serviceName in $startCounter attempts\n");
}
}
sub getDate() {
my $year = $timeInfo[5] + 1900;
my $month = $timeInfo[4] + 1;
my $day = $timeInfo[3];
return sprintf("%04d-%02d-%02d", $year, $month, $day);
}
sub getTime() {
my $hour = $timeInfo[2];
my $min = $timeInfo[1];
my $sec = $timeInfo[0];
return sprintf("%02d:%02d:%02d", $hour, $min, $sec);
}
sub logEvent() {
# Log the event
open(OUT, ">> C:/servicestatus/$currentDate.txt");
print OUT "$_[0]";
close(OUT);
}
答案 0 :(得分:2)
基于下面的一些评论(包括@Ron Bergin的一些不错的观点),我正在修改这篇文章,以显示适合我的代码(Windows 8.1,ActivePerl 5.16)。
#!/usr/local/bin/perl
use strict;
use warnings;
use POSIX;
use Win32::Service;
my $currentDate = getDate();
my %status;
my %status_code = (
Stopped => 1,
StartPending => 2,
StopPending => 3,
Running => 4,
ResumePending => 5,
PausePending => 6,
Paused => 7
);
checkService("Apple Mobile Device");
########
# SUBS
########
sub checkService {
my $serviceName = shift || die "No arg passed";
my $startCounter = 1;
Win32::Service::GetStatus('', $serviceName, \%status);
if ($status{"CurrentState"} eq $status_code{Running}) {
logEvent("$serviceName is running\n");
}
elsif ($status{"CurrentState"} eq $status_code{'Stopped'}) {
my $maxAttempts = 3;
while ($startCounter <= $maxAttempts) {
logEvent("Attempting to start $serviceName");
Win32::Service::StartService('', $serviceName);
sleep(5);
Win32::Service::GetStatus('', $serviceName, \%status);
if ($status{"CurrentState"} eq $status_code{Running}) {
logEvent("Started $serviceName in $startCounter attempts\n");
last;
}
$startCounter++;
}
if ($startCounter eq $maxAttempts) {
logEvent("Unable to start $serviceName in $startCounter attempts\n");
}
}
}
sub getDate {
my @timeInfo = localtime(time);
my $year = $timeInfo[5] + 1900;
my $month = $timeInfo[4] + 1;
my $day = $timeInfo[3];
return sprintf("%04d-%02d-%02d", $year, $month, $day);
}
sub logEvent {
my $msg = strftime("%H:%M:%S", localtime) . ": $_[0]\n";
print "$msg";
open(OUT, ">> C:/servicestatus/$currentDate.txt");
print OUT "$msg";
close(OUT);
}
以管理员身份运行此NOT,输出如下:
14:11:30: Attempting to start Apple Mobile Device
14:11:35: Attempting to start Apple Mobile Device
14:11:40: Attempting to start Apple Mobile Device
以管理员身份运行如下:
14:14:29: Attempting to start Apple Mobile Device
14:14:34: Started Apple Mobile Device in 1 attempts
答案 1 :(得分:1)
我对这个Win32 :: Service模块的一个主要问题是它在失败时返回undef 但是没有设置$!因此找出失败的原因是更多的工作。我没有在检索该错误方面做过任何测试,但它可能是对Win32模块中某个函数的调用。
#!/usr/local/bin/perl
use 5.010;
use strict;
use warnings;
use POSIX qw(strftime);
use Win32::Service qw(StartService GetStatus GetServices);
my $service = shift || 'Apple Mobile Device';
check_service($service);
exit;
###############################################################################
sub check_service {
my $service = shift;
my %status_code = (
Stopped => 1,
StartPending => 2,
StopPending => 3,
Running => 4,
ResumePending => 5,
PausePending => 6,
Paused => 7
);
my (%status, %services);
GetServices('', \%services) or do {
log_event('Failed to retieve list of services');
exit;
};
%services = reverse %services;
if (! exists $services{$service}) {
log_event("'$service' is not a configured Windows service");
exit;
}
if (GetStatus('', $service, \%status)) {
if ($status{"CurrentState"} eq $status_code{Running} ) {
log_event("$service is running");
}
elsif ( $status{"CurrentState"} eq $status_code{'Stopped'} ) {
ATTEMPT: for (1..3) {
log_event("Attempting to start '$service'");
if (StartService('', $service)) {
sleep 5;
GetStatus('', $service, \%status);
if ($status{"CurrentState"} eq $status_code{Running}) {
log_event("Started '$service'");
last ATTEMPT;
}
}
else {
die "StartService() function failed";
}
}
}
}
else {
log_event("failed to retrieve the status of service '$service'");
exit;
}
return;
}
sub log_event {
# Using one of the better loging modules such as Log::Log4perl
# would be a much better and more robust logging mechanism
my $msg = shift;
my $timestamp = strftime("%H:%M:%S", localtime);
my $filename = strftime("C:/servicestatus/%Y-%m-%d.txt", localtime);
open(my $fh, '>>', $filename) or die "failed to open '$filename' <$!>";
say $fh "$timestamp: $msg";
close $fh;
return;
}