how to get the output from: Win32::Process::Create

J

joez3

Hi all,
This might be more a windows question then perl, but lets see if
someone can help me out. I am using Win32::process::Create to start up
an exe. I can get exe to start, but I need to get what is put out on
the command prompt.
If i try text.exe > temp.txt I can start the exe and the temp.txt file
gets created, but nothing is in it. The text is put in another command
prompt window. So this rules out using system () to start the exe.
Then I tried:
open (FHCMD, Win32::process::Create($processObj, $appName,
$commandLine, 1, DETACHED_PROCESS, ".")." |");

while (<FHCMD>) {
print $_;
}

close (FHCMD);

This start the exe, but nothing is put in FHCMD.
Any ideas on how i get the output?
Thanks,
zim
 
P

Paul Lalli

Hi all,
This might be more a windows question then perl, but lets see if
someone can help me out. I am using Win32::process::Create to start up
an exe. I can get exe to start, but I need to get what is put out on
the command prompt.
If i try text.exe > temp.txt I can start the exe and the temp.txt file
gets created, but nothing is in it. The text is put in another command
prompt window. So this rules out using system () to start the exe.

Is there any particular reason you're not just using backticks?

perldoc perlop
(search for qx)

Paul Lalli
 
J

joez3

Paul said:
Is there any particular reason you're not just using backticks?

perldoc perlop
(search for qx)

Paul Lalli

Hi Paul,
I am not sure what the backticks buy me, i can start up the exe with
the Process::Create. Maybe i should have said more about the exe under
test, its a program that will stay up untill I kill it. By using the
Process::Create I can get the pid and use that to kill it. With the
backticks I tried the following:
open (FHCMD, `start test.exe`." | ");
while (<FHCMD>) {
print $_;
}
This starts the test.exe, but it ends up hanging the perl script and I
can't get the contents of FHCMD.
What should I try next?
Thanks,
zim
 
J

joez3

Paul said:
Is there any particular reason you're not just using backticks?

perldoc perlop
(search for qx)

Paul Lalli

Hi Paul,
I am not sure what the backticks buy me, i can start up the exe with
the Process::Create. Maybe i should have said more about the exe under
test, its a program that will stay up untill I kill it. By using the
Process::Create I can get the pid and use that to kill it. With the
backticks I tried the following:
open (FHCMD, `start test.exe`." | ");
while (<FHCMD>) {
print $_;
}
This starts the test.exe, but it ends up hanging the perl script and I
can't get the contents of FHCMD.
What should I try next?
Thanks,
zim
 
P

Paul Lalli

I am not sure what the backticks buy me,

They buy you the ability to get the output of your program, which is
what you said you wanted.
i can start up the exe with
the Process::Create. Maybe i should have said more about the exe under
test, its a program that will stay up untill I kill it. By using the
Process::Create I can get the pid and use that to kill it. With the
backticks I tried the following:
open (FHCMD, `start test.exe`." | ");

This makes just as little sense as your original.
Win32::process::Create returns either 0 or non-zero depending on
whether or not the program was successfully started. Backticks return
the output of the command. You're trying to open a pipe to these
return values, instead of opening a pipe to the actual command.
while (<FHCMD>) {
print $_;
}
This starts the test.exe, but it ends up hanging the perl script and I
can't get the contents of FHCMD.
What should I try next?

You should take a step back and think about what it is you're actually
trying to do, and how to go about doing it. Your last two attempts
have been nonsensical, which is a sure sign that you've reached the
point of frustration and are now throwing things at the wall to see
what sticks.

You apparently have two requirements. One is that you need to capture
the output of the program. The other is that you need to get the pid
of the program so you can later kill it. These two requirements seem,
to me, to be contraditory. The only way it makes sense is if you don't
want your Perl script to do anything else while this program is
running. Is that correct? If so: open a pipe to the process. Start
reading its output. Whenever you've decided you want to kill it, exit
the loop and close the handle. IIRC, that will send a SIGPIPE to the
program, effectively terminating it.

open my $pipe, "test.exe |" or die "Cannot start program: $!";
while (my $line = <$pipe>) {
#do something with $line
if (want_to_kill()) {
last;
}
}
close $pipe;

Paul Lalli
 
P

Paul Lalli

Paul said:
You apparently have two requirements. One is that you need to capture
the output of the program. The other is that you need to get the pid
of the program so you can later kill it. These two requirements seem,
to me, to be contraditory.

I guess the other possibility is to fork your program, and set up the
child to have a signal handler to be notified when the parent wants to
kill it....

[untested]

my $pid = fork();
if ($pid == 0) { #child

$SIG{INT} = sub { print "Parent told me to die!\n"; exit };

open my $pipe, "test.exe |" or die "Cannot open pipe: $!";
while (my $line = <$pipe>) {
process_line($line);
}
print "test.exe ended before parent told me to die!\n";
}
else { #parent
#do stuff
# la la la
if (want_to_kill()) {
kill ('INT', $pid);
}
#do more stuff, la la la
}

Paul Lalli
 
S

Sisyphus

..
..
I am using Win32::process::Create to start up
an exe. I can get exe to start, but I need to get what is put out on
the command prompt.
If i try text.exe > temp.txt I can start the exe and the temp.txt file
gets created, but nothing is in it. The text is put in another command
prompt window.

You can have the output of the executable appear in the *same* command
window by simply specifying 0 or NORMAL_PRIORITY_CLASS as the fifth argument
to Create().
(In a subsequent post you specified DETACHED_PROCESS - and that hides the
output.)

Does that solve the problem ?

Cheers,
Rob
 
P

Peter J. Holzer

You apparently have two requirements. One is that you need to capture
the output of the program. The other is that you need to get the pid
of the program so you can later kill it. These two requirements
seem, to me, to be contraditory. The only way it makes sense is if
you don't want your Perl script to do anything else while this program
is running.

Actually, I think it's just the contrary. If he didn't want to do
anything while the other program was running, he could use
backticks. But apparently he does at least have to decide whether to
kill the program, so he needs more control.

I don't know about Windows, in Unix you would do this with fork and
exec:

my $pid = fork();
die "can't fork: $!" unless defined $pid;
my ($rfh, $wfh);
pipe($rfh, $wfh) or die "can't create pipe: $!";
if ($pid == 0) {
# child: redirect stdout and start program
open(STDOUT, ">&$wfh";
close($rfh);
exec($app);
} else {
# parent: read from pipe
close($wfh);
while (<$rfh>) {
# do something
if (needs_killin()) {
kill $pid;
}
}
wait();
}

hp
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,743
Latest member
WoodrowMea

Latest Threads

Top