我正在使用 Perl 创建 Windows 服务。我正在Win32::Daemon
为此目的使用。
处理服务的 Perl 脚本(接受启动和停止回调等)使用system()
命令调用 .bat 文件,最终调用我的最终 Perl 程序。
问题是,当我停止服务时,由 启动的进程system()
没有关闭,最终进程也没有关闭(由 生成的进程启动system()
)。
这就像进程之间没有“父子”关系(停止Windows服务通常会导致所有相关进程同时关闭)。
编辑:我添加了上面的代码。我刚刚展示了注册服务回调和调用 StartService 的主函数,以及三个主要回调:启动、运行、停止。
sub main {
#registering service callbacks
Win32::Daemon::RegisterCallbacks( {
start => \&Callback_Start,
running => \&Callback_Running,
stop => \&Callback_Stop,
pause => \&Callback_Pause,
continue => \&Callback_Continue,
} );
my %Context = (
last_state => SERVICE_STOPPED,
start_time => time(),
);
Win32::Daemon::StartService( \%Context, 2000 );
# Here the service has stopped
close STDERR; close STDOUT;
}
#function called after the start one
sub Callback_Running
{
my( $Event, $Context ) = @_;
#Here I had to make an infinite loop to make the service "persistant". Otherwise it stops automatically (maybe there's something important I missed here?
if( SERVICE_RUNNING == Win32::Daemon::State() )
{
Win32::Daemon::State( SERVICE_RUNNING );
}
}
#function first called by StartService
sub Callback_Start
{
#above is stated the system() call where I trigger the .bat script
my( $Event, $Context ) = @_;
my $cmd = "START \"\" /Dc:\\path\\to\\script\\dir\\ \"script.bat\"";
print $cmd."\n";
system($cmd);
$Context->{last_state} = SERVICE_RUNNING;
Win32::Daemon::State( SERVICE_RUNNING );
}
sub Callback_Stop
{
my( $Event, $Context ) = @_;
#Things I should do to stop the service, like closing the generated processes (if I knew their pid)
$Context->{last_state} = SERVICE_STOPPED;
Win32::Daemon::State( SERVICE_STOPPED );
# We need to notify the Daemon that we want to stop callbacks and the service.
Win32::Daemon::StopService();
}