Reputation: 1025
My Perl scripts need to work with pathnames that are longer than 260 characters, and I can not turn on the feature in the registry to enable Windows Long Path support.
I included a small Perl test, using the Win32::LongPath
module to do this, and found that only a few functions from that module work. No luck with:
Environment:
I can't really find evidence that Win32::LongPath
will not work in that environment, except for CPAN saying that the module has only been tested on XP and Windows 8...
⚠ However all of the help for Perl/Windows Long Paths in Windows 10 seems to recommend this module?
Am I using it wrong? I have included the output of the last iteration of the loop in the MRE (Minimal Reproducible Example):
chdirL
command never changes directories.getcwdL
command only has 249 characters (513 expected).package main 1.0;
use strict;
use warnings;
use Carp;
use Readonly;
use File::Spec::Functions;
use Cwd;
use Win32::LongPath;
my $dir = 'd123456789';
my $file = 'test.txt';
my $long_path = 'C:\\Temp';
my $long_file;
my $long_root = catdir $long_path, $dir;
my $fh;
# Maximum path length on linux : 4096
# Maximum path length on Windows : 260
Readonly::Scalar my $MAX_PATH => 512;
chdirL $long_path;
while ( length $long_path < $MAX_PATH ) {
$long_path = catdir $long_path, $dir;
$long_file = catfile $long_path, $file;
printf "%-5d: %s\n", length $long_path, "Making $long_path...";
mkdirL $long_path;
# === Does not change directories ==>
chdirL $long_path;
system 'CD';
# === Truncates path name ==>
my $curdir = getcwdL;
printf "%-20s: %s (%d)\n", 'getcwpdL', $curdir, length $curdir;
printf "%-5d: %s\n", length $long_file, "Making $long_file...";
openL \$fh, '>', $long_file or die "unable to create file\n";
print {$fh} "$long_path\n" or die "unable to print to file\n";
close $fh or die "unable to close file\n";
last if ( !( testL 'e', $long_path ) );
last if ( !( testL 'e', $long_file ) );
}
unlinkL $long_file or warn "unable to delete file\n";
1;
Last loop iteration:
513 : Making C:\Temp\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789...
W:\home\_PERL\long_path
getcwpdL : C:\Temp\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789 (249)
522 : Making C:\Temp\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\d123456789\test.txt...
Upvotes: 1
Views: 588
Reputation: 385496
chdirL
is failing with The filename or extension is too long
. chdirL
, like the others, converts the path to a long path (\\?\...
), and calls the appropriate system call. This is SetCurrentDirectoryW
for chdirL
and GetCurrentDirectoryW
for getcwdL
.
Using paths of the form \\?\...
extends the use length limit for some calls, but not for SetCurrentDirectoryW
and GetCurrentDirectoryW
. It also doesn't extend the limit for CreateDirectoryW
, CreateDirectoryExW
and RemoveDirectoryW
. These five retain the classical length limit even when using "long paths", at least according to Maximum Path Length Limitation, which provides a registry setting PLUS a manifest entry you can use to remove the limit on long paths for those calls.
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem]
"LongPathsEnabled"=dword:00000001
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
<ws2:longPathAware>true</ws2:longPathAware>
</windowsSettings>
</application>
I don't remember if DLLs have their own manifest or not. If they do, the settings could be changed for just the module, and nothing would break. If they don't and perl
's manifest needs to be changed, this would affect all uses of GetCurrentDirectoryW
in the process, and that could cause problems. (GetCurrentDirectoryW
could return an error because the buffer is too small, which could lead to a failure or crash depending on whether error checking is performed.)
Upvotes: 2