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

Ok fine monks, let's see what I am doing wrong. I want to create a process, return any error messages then decide what to do next if I do not receive an error message.

I can initiate the process. However I am not sure how to do the following:
-waiting for the process to complete, then
-killing the process should it start to error

I was using system(), but Win32::Process seems to be a better way to go. But again, the application/process I am running creates a program error on certain files, waiting for an ok/cancel... if I see this I want to close it down... but first I must have the script to wait until the process is done, then get information on whether the process was successful

Does that sound clear?

Please advise kind Monks.

Replies are listed 'Best First'.
Re: Win32::Process handling
by Rich36 (Chaplain) on Jun 24, 2002 at 19:48 UTC
    Not sure about the second part since I'm not sure what you're calling - that may need to be handled in the process - but waiting for the process to end is pretty simple.
    Win32::Process::Create( my $process, 'C:/path/to/executable.exe', "commandgoeshere", 0, NORMAL_PRIORITY_CLASS, '.', ) or die "Could not start process\n"; # Wait for the process to complete before continuing in the applicatio +n $process->Wait(INFINITE); # You can also set a particular time

    «Rich36»
Re: Win32::Process handling
by Jenda (Abbot) on Jun 24, 2002 at 21:05 UTC

    How does the process report the error? Does it create a file somewhere? Or does it show a dialog box? Does it write something to STDERR?

    If the first, you only need a loop similar to this:

    my $loopcount = 0; 1 while (! $process->Wait(1000) and ! -e $the_file and $loopcount++ < +$timeout); if ($loopcount >= $timeout) { ... fead up with waiting. } elsif (-e $the_file) { ... it errored out } else { ... it did its work }

    In the second case you should try it Win32::GuiTest's FindWindowLike() sees that error message box and then the loop will be similar. Just instead of -e $the_file you'll have something like FindWindowLike(0, "^My program error", undef). Plus maybe it'll be better if you find the main program window first and then only search among its children.

    In the third case you'll have to

    1. store the STDIN, STDOUT and STDERR
    2. close them and open them to something else. Most probably you will want to pipe() to STDIN and open STDOUT and STDERR to a file (keep in mind that you cannot select() on anything but socket()s under Windows, AFAIK)
    3. start the process with INHERIT_HANDLES flag
    4. restore STDIN, STDOUT and STDERR
    5. print whatever you need to the pipe() leading to the program's STDIN (and hope the pipe is big enough and/or the program is reading)
    6. loop and test the files to that the process's STDOUT and STDERR write

    I can go into more detail on the 2nd and 3rd if that is what you need.

      Jenda@Krynicky.cz

Re: Win32::Process handling
by boo_radley (Parson) on Jun 24, 2002 at 21:47 UTC
    let's say we have a process, $process :
    if ($process->Wait (60*1000)){ # execution of the process is successfully. $process->Kill(0); } else { # process has hung up for some reason handle_process_problem (); notify_sysop(); $process->Kill(255) }
    you might also look for a particular dialog box's title, and take appropriate action, using Win32::Setupsup and its GetWindowTitles method.