windows - 调用 system() 不会在我的 Windows 进程之间创建父子关系

标签 windows perl process windows-services

我正在使用 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();
}

最佳答案

在 Windows 中,进程之间没有父子关系。 Windows 将所有进程视为对等进程,特别是杀死“父进程”永远不会杀死“子进程”。

当服务收到停止请求时,它负责关闭/终止它可能已经创建的任何进程(如果这样做是合适的)。

您说“停止 [原文如此] Windows 服务通常会导致所有相关进程关闭”,但通常情况并非如此;也许 Win32::Daemon 正在为您做这件事,但当然它无法知道从您的批处理文件启动的任何进程。

如果可能的话,正确的解决方案是在单个进程中实现您的服务。由于在这种情况下,两个进程都是用 Perl 编写的,因此将它们组合成一个程序应该相对简单。

关于windows - 调用 system() 不会在我的 Windows 进程之间创建父子关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10243802/

相关文章:

linux - "Max open files"工作进程

带有goto命令的windows批处理文件不起作用

perl - 闭包中的局部变量可见性与局部 `sub` s

php - 3XX 重定向的自定义错误文档

c - 如何在 C 中设置环境变量并启动进程?

c - 在C中,如何创建多个子进程(不知道需要多少个)?

c# - Azure:如何创建对内部端点的服务引用

windows - for 循环的批处理脚本不起作用,仅循环一次

c++ - 为 Wchar_t 替换双反斜杠

Linux:使用行号作为变量将变量附加到行尾