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

Hello Monks,

I have a Tk widget that invokes the following as part of its callback

sub open_excel_file { my ( $path_of_excel, $file_to_open, ) = @_; use File::DosGlob 'glob'; my $prob_found = system glob($path_of_excel), $file_to_open; #my $prob_found = system( (glob qq{"$path_of_excel"}), $file_to_open); return ( $prob_found ? 'red' : 'green' ); }

I let the user configure a string like the following to hold the path to Excel (user runs app on Win32 for user's own benefit.) I store this string in a variable and pass it as a parameter for $path_of_excel, along with an absolute path name of a $file_to_open that I generate with catfile.

C:\\Program\ Files\\Microsoft\ Office\\Office\\Excel.exe

Using either of the 'system glob' calls, a new instance of Excel starts, quickly accessing the file.

When I try the following string, again using either of the 'system glob' calls, it takes a LONG time for Excel to open and access the file. I'd like to let the user configure pathnames like the following since otherwise I expect my users to quiver if I tell them to use backslashes to escape backslashes and spaces. (It's bad enough making them go verify the path to Excel.) But I can't if it takes so long. Any thoughts as to what's going on and how to make the following format start up faster? Thanks.

C:\Program Files\Microsoft Office\Office\Excel.exe

(And yes, once you explain the problem with the single-slash approach, you are welcome to suggest entirely different ways of opening an Excel session for the user to fool around in; the program should wait/sleep while the user does his/her thing with the file in Excel, then be ready to run again when the user Saves/Closes. :-)

Replies are listed 'Best First'.
Re: Win32 spaces in path, open Excel w/ 'system' and glob/DosGlob
by jmcnamara (Monsignor) on Oct 23, 2003 at 07:50 UTC

    You can escape the backslashes using quotemeta:
    #!/usr/bin/perl -wl my $str = 'C:\Program Files\Microsoft Office\Office\Excel.exe'; $str = quotemeta $str; print $str; __END__ prints: C\:\\Program\ Files\\Microsoft\ Office\\Office\\Excel\.exe

    Or convert the backslashes to forward slashes:

    $str =~ s[\\][/]g;

    --
    John.

      Thanks John, it appears that quotemeta will do the trick.

      Using the forward slash approach works if there are no spaces but my memory says that glob would then treat the space as an IFS character and not use the whole command string for Win32 to see when invoking system. Portions after the space would be treated as arguments for the (now bogus) command before the space.

      Brig

      (re "my memory says": I developed this portion of my app SEVERAL months ago and am trying to resolve interface issues like this before I release to a wider circle of users.... :-)

      Update: My memory also says that, as a fan of File::Spec and catfile, I was sorely disappointed when I couldn't finagle a way to get its output to work well when invoked by system, again plagued by system losing something in the translation: Win32 did not like being passed a command whose absolute path name included forward slashes. I believe that the embedded spaces were difficult, too....

      Perhaps I should go get some fresh complaints (test results) from using File::Spec output....

Re: Win32 spaces in path, open Excel w/ 'system' and glob/DosGlob
by nimdokk (Vicar) on Oct 23, 2003 at 10:05 UTC
    You might also try using File::Spec to help you out with the path information.

    use strict; use warnings; use File::Spec; my $path=File::Spec->catfile('C:',"Program Files","Microsoft Office"," +Office","Excel.exe"); print "\$path gives you: $path\n"; __END__ Output: $path gives you: C:\Program Files\Microsoft Office\Office\Excel.exe.
    Of course, the spaces in the path might still give you problems. You may need to use literal quotes around the path to prevent problems.


    "Ex libris un peut de tout"

      Using File::Spec is always a good idea in my book. If you want your file path code to work on multiple platforms (and to be honest, why wouldn't you?) then using File::Spec takes all the pain away and leaves you free to worry about other things instead :-)

      -- vek --