Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Opening files for other exes in Windows

by ecuguru (Monk)
on Aug 22, 2006 at 04:56 UTC ( [id://568763]=perlquestion: print w/replies, xml ) Need Help??

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

Hey guys, I could really use some help.
I've got a desktop application in Perl running on Windows that grabs data and writes it to a formatted file, and opens the file for viewing in its own view program.

The problem is that, if the viewer program of the file (notepad, googEarth, etc), isn't already open, the call to open the file never returns home and my program hangs.
Im using
print "Opening file: $File\r\n"; my $returnValue = system($File); # my $returnValue = exec($File); print "Done. ReturnValue $returnValue\r\n";
So if the data viewing program is already open I'm fine and it runs great. If however I open the file and the viewer is not open, Perl will hang at the system or exec calls waiting for the exe to quit. Is there a way to spawn the system call in a separate thread or some other means such that I'm not hanging the program waiting for the user to close the viewing exe?
Thanks!

Replies are listed 'Best First'.
Re: Opening files for other exes in Windows
by Corion (Patriarch) on Aug 22, 2006 at 06:31 UTC

    Neither of the two other solutions are what I'd use on Windows to start a detached process. The ampersand-method doesn't work on Windows, because the interpretation of the ampersand is shell-dependent. I stay away from fork() because it brings many problems with it whenever shared resources are released.

    On Windows, you have three methods of launching a process detached from the main program. The easy way is to use the start command of cmd.exe, see help start for more information:

    system( "start $File");

    to launch $File detached from your program.

    If you want to go to the bare metal, there is the CreateProcess function which you can access via Win32::API to create a process.

    If you want to stay close to Perl, you can use

    system( 1, $File );

    which is a bit underdocumented and does weird things to your console window, but otherwise also spawns an independent process.

      Forking did indeed fail, and the & didn't work in Windows But both sets of advice were good knowledge for me.

      I'm doing really well with (1,$file)
      Is there a performance difference in calling a file with system($file); and system("start $file");?
      Gotta keep at it, but it's a lot closer now. Many thanks!
Re: Opening files for other exes in Windows
by Roger (Parson) on Aug 22, 2006 at 05:59 UTC
    To start with, perl exec is not going to return control to the calling program.

    perldoc -f exec exec LIST exec PROGRAM LIST The "exec" function executes a system command and never returns-- use "system" instead of "exec" if you want it to return. It fails and returns false only if the command does not exist and it is executed directly instead of via your system's command shell (see below).

    To spawn another process is quite easy in Perl. The following code will do what you want:
    ... my $pid = fork(); if (undefined $pid) { die 'Fork failed'; } if (!$pid) { # I am in the child process system $MYCOMMAND; exit; } # I am in the parent process # continue with other business ...
Re: Opening files for other exes in Windows
by cdarke (Prior) on Aug 22, 2006 at 06:41 UTC
    It is not clear if $File is an executable or a data file. File association is not done by the OS in Windows, the application must do it by looking up the registry. You can find the program associated with a file (and extension) using Win32::FetchCommand (CPAN) which will do the registry lookup for you. It is actually designed to work with Win32::Process::Create, but should work OK with system().
Re: Opening files for other exes in Windows
by Mandrake (Chaplain) on Aug 22, 2006 at 06:16 UTC
    >Is there a way to spawn the system call in a separate thread or some other means such that I'm not hanging the program waiting for the user to close the viewing exe?
    Say
    my $File = "perl script.pl &" my $returnValue = system($File); print "Done. ReturnValue $returnValue\r\n"; #rest of the program goes here
    Please note the ampersand (&) in the system call.
    Here, the system will not be waiting for the execution of the script specified in the $File variable. It just proceeds with the next line and the system call will be running in the background.
    Is this what you need?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://568763]
Approved by McDarren
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (3)
As of 2024-04-20 13:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found