Opening a file with its Windows app in Activestate

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

•  Subject
• Author
• Posted on
I've got Activestate Perl on my win7/pro system.  I've poked through the
win32 man pages and I just can't quite figure it out: I'm guessing there
must be some easy way for my perl program to tell windows "open <FILE.PDF>"
and have the PDF app open the file [and presumably some way I can wait
until it exits], or to explicitly say what program, like "OPEN <FILE> with
<EXCEL>"  Any pointers to what to look at in the docs would be appreciated.
THANKS!.

/Bernie\
--
Bernie Cosell                     Fantasy Farm Fibers
bernie@fantasyfarm.com            Pearisburg, VA
-->  Too many people, too few sheep  <--

Re: Opening a file with its Windows app in Activestate

I suppose you could dig through some Windows API somewhere to find out
which program is configured to open which file type. But why not let
Windows do the heavy lifting? A simple
system ('file.pdf');
will do the job nicely.

Please note that very often Windows programs will run in a forked
process, i.e. system() will return immediately and the application
program will run independantly in a separate process.

jue

Re: Opening a file with its Windows app in Activestate

The only easy way to open a file with a specific program is to locate
the .exe and pass it the right arguments to get it to open the file.
*Usually* invoking (e.g.)

c:\path\to\excel.exe c:\path\to\some.xls

is sufficient, but not always. (Remember to be careful about quoting.)
You may need to (locate and) read the documentation for the program
you're invoking.

As Jue says, there are Windows APIs for this sort of thing, and it is
always possible to go in that way. For instance, when it comes to Office
applications (and other apps that play nicely with OLE), you can use
Win32::OLE to get Excel to open the file without having to find out
where Excel is installed.

Are you sure? I would be surprised. IIRC from the command-line you have
to run

start file.pdf

and it won't wait. (In general it can't wait, because the file might be
passed to an already-running instance of the appropriate program.)

Forked? :)

This is almost never the case if you invoke an application directly;
however, if you invoke it through 'start' then I believe start.exe will
just contact a running Explorer process to perform the file open, and
will exit as soon as it's done that.

Ben

Re: Opening a file with its Windows app in Activestate

Yes. I tried it before I posted the reply.
Of course *.PDF has to be associated with the proper program.

Correct. Maybe some system() magic on Windows?

Agreed again.

Just try a simple
from a DOS command prompt, without a preceeding 'start'.

Maybe that's the mechanics behind the scene. And yes, when called with
'start', then this adds an additional layer and even the few programs
that normally would cause system() to wait will now run in parallel.
The important point from a Perl programmers point of view is that for
many Windows program system() will not wait for them to finish, even
when not using 'start' but calling the exe directly.

Been there, done that. At the end for this particularly nasty program
the only somewhat reliable way to determine if it was still running was
to check the process table in regular intervals.

jue

Re: Opening a file with its Windows app in Activestate

Huh. I didn't know that. I don't think this is anything perl is doing:
it just passes the given command-line to CreateProcess, and if that
fails it tries again prepending 'cmd.exe /x/d/c'. This must be a cmd
'feature', I think; perhaps a new one. IIRC it used to be necessary to
put the extension into some environment variable before you could invoke
it directly.

Hmm. It's been a while since I've done any serious work on Windows; I
don't remember this behaviour. In any case it can't be the application
that's forking, since Windows processes don't fork; this must again be a
cmd.exe thing. If perl creates the process directly (i.e. if the
invocation without cmd.exe succeeds) it will wait for it to exit.

IME the only even-remotely reliable way to invoke real Windows programs
(rather than ported Unix programs, which tend to behave a little
differently) is to use Win32::Process directly. The Create call will
always return immediately, but you can then call ->Wait to wait for it
to terminate. (Obviously if you used 'start' this still won't get you
anywhere.)

Ben

Re: Opening a file with its Windows app in Activestate

Thanks for the advice.  It wouldn't have occurred to me that
system("mysheet.xls")

would do the right thing and actually start Excel.  If it does return
immediately, I can always wait for the user to hit <ENTER> or something to
move on [the user leaving Excel running or not, at their pleasure]

} IME the only even-remotely reliable way to invoke real Windows programs
} (rather than ported Unix programs, which tend to behave a little
} differently) is to use Win32::Process directly. The Create call will
} always return immediately, but you can then call ->Wait to wait for it
} to terminate. (Obviously if you used 'start' this still won't get you
} anywhere.)

AHA!   I couldn't quite figure that out through the win32 docs.  But I see
it now:

Win32::Process::Create($ProcessObj, "C:\winnt\system32\notepad.exe", "notepad temp.txt", 0, NORMAL_PRIORITY_CLASS, ".")|| die ErrorReport(); that's perfect! [there's even with a ->wait method!]. The second are is just given as "command line args" I guess that means a string, with double-quotes in the necessary places and spaces between the args, just as in cmd.exe. And more poking around in the activestate docs [I wish there was a better search!] I found: ActiveState::Win32::Shell - Windows Shell Functions FindExecutable($document )

Returns the executable registered to open the $document or undef. So presumably that could be used to find the first argument to feed to Process::Create. Oh boy... if this all works it'll be a miracle...:o) THANKS!! /bernie\ -- Bernie Cosell Fantasy Farm Fibers bernie@fantasyfarm.com Pearisburg, VA --> Too many people, too few sheep <-- Re: Opening a file with its Windows app in Activestate On 10/2/2013 6:12 PM, Ben Morrow wrote: Running this twice: perl -e "0==system('foo.pdf') or die$?"

The first waits and the second doesn't.  However, in both cases, the
wait call will return 256 even exiting Adobe normally.

Peek behind those dark doors at your own peril...

--
Charles DeRykus