Consider looking at perlop to see what -x does. Also, if it "always fails" (and you're interested in learning why), consider posting full code.
Please note that dir and date are shell builtins in cmd.exe and thus never pass -x, because they are not programs that can be run. Also note that -x expects the full path to an executable and does not search $ENV{PATH}. Whether that is desired or not in the context of the above program, I don't know. Update: As the argument is passed to Win32::Process::Create(...), it makes sense to have a fully specified path, because that's what Win32::Process::Create() likely wants.
>perl -wle "print $_, -x $_ ? ' yes':' no' for @ARGV" cmd.exe c:\WINDO
+WS\system32\cmd.exe
cmd.exe no
c:\WINDOWS\system32\cmd.exe yes
As to using system or backticks, these do not launch a background process. Which seems to be the purpose of the code under discussion. Actually, perlport points out system(1, ...) for launching a process in the background under Windows and OS/2. | [reply] [Watch: Dir/Any] [d/l] [select] |
use Proc::Background;
timeout_system($seconds, $command, $arg1);
timeout_system($seconds, "$command $arg1");
my $proc1 = Proc::Background->new($command, $arg1, $arg2);
my $proc2 = Proc::Background->new("$command $arg1 1>&2");
$proc1->alive;
$proc1->die;
$proc1->wait;
my $time1 = $proc1->start_time;
my $time2 = $proc1->end_time;
# Add an option to kill the process with die when the variable
+ is
# DETROYed.
my $opts = {'die_upon_destroy' => 1};
my $proc3 = Proc::Background->new($opts, $command, $arg1, $arg
+2);
$proc3 = undef;
| [reply] [Watch: Dir/Any] [d/l] |
Thanks very much for your help and information. With this info I could solve my issues rapidly.
I rebuild the example of Peter Dragon for my usage:
sub start_child
{ my $Cmd = $_[0];
my $CmdOptions = $_[1];
my $ChildProc;
my $ChildPid;
die "cannot execute cmd: $Cmd" unless (-x "$Cmd");
require Win32::Process;
Win32::Process::Create($ChildProc, $Cmd, $CmdOptions, 0, 0, ".") ||
+confess "Could not spawn child: $!";
$ChildPid = $ChildProc->GetProcessID();
# catch early child exit, e.g. if program path is incorrect
sleep(1.0);
POSIX::waitpid(-1, POSIX::WNOHANG()); # clean up any defunct child p
+rocess
if (kill(0,$ChildPid))
{ print "Started child process id $ChildPid\n";
}
else
{ warn "Child process exited quickly: $Cmd: process $ChildPid";
}
return $ChildPid;
}
$ChildPid = start_child($Cmd1, $Cmd1Options);
sleep(5.0);
$ChildPid = start_child($Cmd2, $Cmd2Options);
At the moment I stop the childs by TASKKILL /F /PID of the commands I've started. Not the nicest solution, better to do it with interrupts, but I haven't read that part of the Perl cookbook yet ;) | [reply] [Watch: Dir/Any] [d/l] |