为什么在 Perl 脚本中使用 Windows API 函数 createDirectoryW 会失败?

Why does Windows API function createDirectoryW fail when used from a Perl script?

我正在使用 perl 对文件进行一些处理。我们从特定位置复制文件,对每个文件进行一些处理,然后将文件复制到处理后的位置。如果在源目标中我们有文件夹,那么我们也会在目标文件夹中创建相同的结构。在 perl 脚本中,我们使用 createDirectoryw 创建文件夹结构。

use Win32::API;
use Encode qw(decode encode);

use Encode::Unicode;       # GBR

use Symbol qw( gensym );
use Win32API::File qw(CreateFileW OsFHandleOpen CREATE_ALWAYS GENERIC_WRITE);

$cd = Win32::API->new( 'kernel32', 'CreateDirectoryW', 'PP', 'N' );


...

..

..
my $UTF16_dirname = encode( "UTF-16LE", "$dirname[=12=]" );
my $res = $cd->Call( $UTF16_dirname, 0 ) ;

我得到了 $res as 0,它没有创建文件夹。

看看这个例子,它对我来说很好用:

use strict;
use warnings;
use Win32::API;

use Carp;
use Encode qw( encode );

Win32::API->Import(
    Kernel32 => qq{BOOL CreateDirectoryW(LPWSTR lpPathNameW, VOID *p)}
);

my $path = '\\?\c:';

my $counter=255;

while ($counter)
{
    my $nextDir="\testdir".$counter;

    $path.=$nextDir;

    mk_long_dir($path);

    $counter--;
}

sub mk_long_dir {
    my $path = shift;

    my $ucs_path = encode('UCS-2le', "$path[=10=]");
        CreateDirectoryW($ucs_path, undef)
            or croak "Failed to create directory: '$path': $^E";

    return $path;
}

还要感谢 Sinan Ünür (How do I create then use long Windows paths from Perl?)

现在有一个很棒的模块 Win32::LongPath,它使您不必再胡闹了(其他方面非常出色和无价)Win32::API

所以,使用Win32::LongPath::mkdirL。如果您需要将路径传递给外部程序,请使用从 Win32::LongPath::shortpathL.

获得的路径