I have done a similar thing to what you describe. Although I have never used open3. I always use Win32::Process to spawn my "children" processes.
Below is some code I ripped from some production code which launches several process that all have the same NAME but will obviously have different PIDS.
I have to keep the PIDS in an array, each process that I launch also has some kind of unique identifier.
foreach my $md (@chk_mds) { #@chk_mds is a list of the unique ident
+ifiers (I.e SrvA, SrvB, SrvC etc)
#Read What Kind of Process to Start.
if (!&Spawn($md)) {
&Update_Log("Problems Spawning $proc[0] Process for $md");
}
sleep(1);
}
#Re-Spawn the broken Process
sub Spawn
{
my $rc = 0;
my $md = shift;
my $result = Win32::Process::Create( $ProcessObj,
"$xcall_path/bin/application.exe",
"application.exe $md",
1, #Inherit Handles.
NORMAL_PRIORITY_CLASS,
".") or &Update_Log("DEBUG - Cannot Launch the X-$
+proc process: $!");
if ($result) {
my $pid = $ProcessObj->GetProcessID();
$proclst{$md} = $pid;
push (@pids, $pid);
&Update_Log("\@pids = @pids");
&Update_Log("Launching Call Logger Process for $md with PI
+D - $proclst{$md}");
$rc = $pid;
} else {
&Update_Log("Process for $md NOT successfully Created:" .
+Win32::FormatMessage(GetLastError()));
}
return($rc);
}
#Update Log file
sub Update_Log
{
my ($ss, $mm, $hh, $d, $mon, $yr) = localtime();
my $date = sprintf("%02d-%02d-%04d", $mon+1, $d, $yr+1900);
my $time = sprintf("%02d:%02d:%02d", $hh, $mm, $ss);
#Specify the Logfile Name
my $logfile = "$xcall_path/log/X-CallServer$date.log";
if (open( LOG, ">>$logfile" ) ) {
my $TempSelect = select( LOG );
$| = 1;
select( $TempSelect );
if (! $_[0]) { return (0); }
print LOG "$time - $_[0]";
} else {
&Event(EVENTLOG_ERROR_TYPE, "X-CallServer Could Not Open Logfi
+le $logfile: $!");
exit(5);
}
close(LOG);
return(1);
}
So what I have is a hash (%proclst) of all my application.exe's PIDS. I then have a piece of code that kills these PIDS when the service stops.
foreach my $pid (keys %proclst) {
Win32::Process::KillProcess($proclst{$pid}, 255);
&Update_Log("Service Stopping - Stopping $proclst{$pid}");
}
undef %proclst;
These are only snippets from a larger piece of code, I am using Win32::Daemon for all my service requirements on Win32 also. The Update_Log is a routine that I use to update log files etc.. Really only included so you dont get confused when you see me call it from the Spawn function.
HTH..
-----
Of all the things I've lost in my life, its my mind I miss the most.