Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

How to pass a folder name to Windows external commands?

by freonpsandoz (Beadle)
on Mar 04, 2022 at 01:05 UTC ( #11141819=perlquestion: print w/replies, xml ) Need Help??

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

I'm trying to pass paths that are folder names and that may contain non-ANSI characters to external commands in Windows. I've tried both Win32::GetANSIPathName and Win32::LongPath::shortpathL. The former seems to always return the original path and the latter seems to always return an empty string. What am I doing wrong? Thanks.

use v5.16; use strict; use warnings; use Win32 (); use Win32::Console (); use Win32::LongPath qw(shortpathL); Win32::Console::OutputCP(65001); # Request Windows console command out +put in UTF-8 my $top = shift; foreach my $foldername ( map { chomp $_; $_ } qx(dir /b /a:d "$top") ) + { my $path = "$top\\$foldername"; test( "GetANSIPathName", $path, Win32::GetANSIPathName("$path") ); test( "shortpathL", $path, shortpathL($path) ); } sub test { my ($name, $path, $testpath) = @_; my @report = qx(robocopy /njh /nfl /ndl /np /l /s "$testpath" "x:\ +\nodir"); print( qq($name path "$testpath" didn't work for "$path"\n) ) unless grep(/^ *Bytes/, @report); }

Replies are listed 'Best First'.
Re: How to pass a folder name to Windows external commands?
by haukex (Archbishop) on Mar 04, 2022 at 06:20 UTC

      I created several directories and files with non-ANSI filenames, and the following code works fine on them - it iterates over the short names such as "C:\\Temp\\testuni\\5E71~1\\BF49~1.TXT".

      use warnings; use strict; use Path::Class 'dir'; use IPC::Run3 'run3'; use Data::Dump; my $dir = dir("C:\\Temp\\testuni"); $dir->recurse( callback => sub { my $path = shift; if (!$path->is_dir) { run3 ['hex', $path], undef, \my $out; dd "$path", $out; } });

      Don't use dir to get a list of filenames, which is why I'm using Path::Class (at the very least, use readdir). Please show a runnable, representative SSCCE that demonstrates the problem you're having, including sample input (directory structure), expected output for that input, and the actual output you're getting including any error messages.

      And by representative I also mean to please show the actual command you're running, assuming it isn't robocopy - since its /l option means to just list files, I'm not sure what you're doing with that command in your sample code. One of the things discussed in The problem of "the" default shell, which is linked from my node referenced above, is that a common mistake is to shell out to commands that should be implemented in native Perl.

        I'll try to generate a better example.

        I'm using 'dir' in an attempt to glob a filespec and get Unicode filenames, which File::Glob::Windows doesn't seem to do. Will Path::Class do that? I'm using robocopy /l to get the total size of a folder, including subfolders. It's supposed to be a fast way to do that.

        I tried using run3, but I don't understand its rules and haven't got it working yet. Is 'hex' a command in your example? Is there a reason that you used short pathnames? Thanks.

Re: How to pass a folder name to Windows external commands? (Unicode)
by Anonymous Monk on Mar 04, 2022 at 12:10 UTC
      Shortpathname has caveats, cmd.exe dir wildcards with short names, real surprise after a few decades. , newer versions of windows dont turn on 8.3 names by default

        Short pathnames will work for my folders, but not for my files. One of the commands I execute to check FLAC files needs the Unicode pathname because it doesn't recognize .FLA files.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11141819]
Approved by dorko
Front-paged by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (3)
As of 2022-08-10 05:49 GMT
Find Nodes?
    Voting Booth?

    No recent polls found