markusk has asked for the wisdom of the Perl Monks concerning the following question:

Hi guys, I've been given a command line program that is an executable (.exe) that I was asked to automate on Win32. The task was simple; First enter a number, Enter a string, than 'Press any key to continue...' (dos system call it seems). And the program will reply successful if those values were valid. I decided to use IPC::Open2. The code was as follows..
use strict; use warnings; use IPC::Open2; my $cmd = 'C:\temp\abc.exe'; my $pid = open2(*RR,*WW,$cmd); print WW "5 \n"; print WW "iAmString \n"; print WW "\n"; # any key while (<RR>) { chomp($_); print "$_\n"; } print "done \n";
But the code did not work at all - it froze on the <RR> block. So I went ahead a compiled a simple C code to simulate the problem.
int main(int argc, char** argv) { printf ("Hello World \n"); int value1; printf ("I am a number: "); scanf("%d", &value1); printf ("This is your number: %d \n",value1); char ppp[20]; printf ("I am a string: " ); scanf("%s",&ppp); printf ("This is your string? %10.10s \n",ppp); // system("PAUSE"); return (EXIT_SUCCESS); }
And, the perl script was stuck at the blocking <RR> as expected. I changed the C Program and removed the 'system("pause") - press any key to continue' command, and it worked brilliantly. It appears to me that after the main part of the C program is executed it is blocked by 'cmd.exe /c PAUSE' that I believe is spawned as a blocking child process. i.e i can't write "<any key>" to the process I created through open2. Rather I might have to send <any key> to the cmd.exe that was spawned as a child of abc.exe. Is there a workaround for this? (I don't have access to the source code of the executable, so i can't simply remove the system("PAUSE"). Help is a appreciated.

Replies are listed 'Best First'.
Re: Perl Open2/3 and .exe
by ikegami (Patriarch) on Jun 17, 2009 at 21:15 UTC

    i can't write "<any key>" to the process I created through open2

    No, the problem isn't with writing. As you said yourself, <> is blocking, and that's a reading operation.

    <> reads until a newline is encountered (by default). However, "Press any key to continue . . ." doesn't end with a newline. Since you told perl to read until a newline is encountered. Perl happily waits for more input that will never come. Obviously, <> is not the right choice here, at least not with the default value for $/.

    In addition to that problem, the output of abc or pause could be buffered, but you haven't shown that you've encountered that problem yet. Hopefully it isn't. since you'll have to convince them their STDOUT is connected to a console while it's actually connected to a pipe.

    Update: Oh wait, you don't actually wait before sending \n. hmmm, let me test a bit.

Re: Perl Open2/3 and .exe
by ikegami (Patriarch) on Jun 17, 2009 at 21:31 UTC

    system or pause is clearing the input queue, so you're sending the newline too soon.

    For testing, I put sleep(2) before the print WW "\n";, and it worked fine.

    Finding when to send the newline accurately will be tricky given what I said in my earlier response.