gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 11:09:06 25 4
gpt4 key购买 nike

我正在使用 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com