http://www.perlmonks.org?node_id=1070319


in reply to various questions about Win32::Process

Your problem is Win32::Process doesn't fully expose the C function CreateProcess, where you can specify the initial (since the child can switch them out to whatever it wants programatically if it wants) standard handles the child process will get. I modified your script to get cmd.exe's child's PID and changed away from sleep.exe to perl.exe.
use warnings; use strict; use Win32::Process; use Win32::Process 'STILL_ACTIVE'; use Win32::Process::Info qw{WMI}; my $child_pid; my $real_child_pid; my $child_proc; my $cmd = 'perl -e"sleep 20"'; my $debug = 1; my $exitcode = 1; my $stdout = 'out.txt'; my $stderr = 'err.txt'; Win32::Process::Create($child_proc, $ENV{COMSPEC}, "/c $cmd > $stdout +2>$stderr", 0, 0, ".") || print Win32::FormatMessage( Win32::GetLastE +rror()); $child_pid = $child_proc->GetProcessID(); my $pi = Win32::Process::Info->new(); my ($min_time,$max_time,$kill_time) = (12,15,18); if($child_pid!=0) { print "Started child process id $child_pid\n"; my %subs = $pi->Subprocesses($child_pid); my $real_child_pid = $subs{$child_pid}[0]; print "Real child process id $real_child_pid\n"; #use Data::Dumper; #print Dumper(\%subs); my $i=0; while ( 'true' ) { $child_proc->Wait(1000); $i++; $child_proc->GetExitCode($exitcode); if ( $exitcode == STILL_ACTIVE ) { print "loop $i\n"; if($i==$max_time) { print "max time : this is quite long...\n"; } if($i==$kill_time) { print "kill time : kill $child_pid\n"; $child_proc->Kill(-1); } } else { print "### E = $^E ?=$? ###\n"; print " Process terminated on it's own rc=$exitcode \n"; if($i==$min_time) { print "min time : command was too short\n"; } exit $exitcode; } } } else { print "Can't start process...\n"; }
What you want to use is IPC::Run3 or a Perl wrapper around CreateProcess that exposes http://msdn.microsoft.com/en-us/library/windows/desktop/ms686331%28v=vs.85%29.aspx, specifically "HANDLE hStdOutput" (and according to grep.cpan.me, there is only 1, and its a personal module intended to never be used by the public (https://metacpan.org/release/DAVEROTH/Win32_AdminMisc_Source_980511), choice 3 is using Win32::API and calling CreateProcess yourself with that struct.