Как создать каталог Unicode в Windows, используя Perl? - PullRequest
5 голосов
/ 02 февраля 2010

Я пытаюсь создать имена каталогов, содержащие Юникод . Я на Windows XP и Perl Camelbox 5.10.0.

До сих пор я использовал use File::Path qw ( make_path ) для создания каталогов, которые работали до тех пор, пока не появился первый каталог кириллицы.

Для файлов Win32API::File qw ( CreateFileW ) работает нормально, если имя файла в кодировке UTF-16LE. Есть ли что-то подобное для каталогов? Или, может быть, параметр, сообщающий CreateFileW о создании пути Unicode, если он не существует?

Спасибо,
Неле

Ответы [ 2 ]

6 голосов
/ 02 февраля 2010

Win32.pm предоставляет интерфейс для CreateDirectory и друзей:

Win32::CreateDirectory(DIRECTORY)

Создает DIRECTORY и возвращает истинное значение в случае успеха. Проверьте $^E в случае сбоя для расширенной информации об ошибке.

DIRECTORY может содержать символы Unicode вне системной кодовой страницы. После создания каталога вы можете использовать Win32::GetANSIPathName(), чтобы получить имя, которое можно передать системным вызовам и внешним программам.

Предыдущий ответ:

Примечание: Сохраните это здесь для записи, потому что вы пытались использовать CreateDirectoryW непосредственно в вашей программе.

Для этого вручную импортируйте CreateDirectoryW, используя Win32 :: API :

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

Вам необходимо кодировать $path для CreateDirectoryW:

#!/usr/bin/perl

use strict; use warnings;
use utf8;

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

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

binmode STDOUT, ':utf8';
binmode STDERR, ':utf8';

my $dir_name = 'Волгогра́д';

my $ucs_path = encode('UCS-2le', "$dir_name\0");
CreateDirectoryW($ucs_path, undef)
    or die "Failed to create directory: '$dir_name': $^E";
E:\> dir
2010/02/02  01:05 PM              волгогра́д
2010/02/02  01:04 PM              москва
0 голосов
/ 12 апреля 2018

Просто обновляю этот вопрос к 2018 году.

Невероятно, ActivePerl 5.24 все еще не поддерживает просто передачу путей Unicode в open() / mkdir() и расширением File::Path::mkpath(), потому что базовый код Perl по-прежнему вызывает версию ASCII 20-го века Windows CreateFile(). Безумие! Как это могло быть не более высоким приоритетом, чем бесчисленные неясные изменения Perl, сделанные за прошедшие 10 лет?!

Это верно даже , если вы используете utf8; или множество других заклинаний.

Так что даже сегодня у нас все еще должен быть специальный код для Windows для этой самой основной функции (создание / доступ к именам файлов Unicode).

К счастью, модуль Win32::Unicode имеет приятную, простую в использовании функцию Win32::Unicode::Dir::mkpathW(), которая делает именно то, что вам нужно, и работает для Unicode (а также великолепные функции copyW() и moveW()).

К сожалению, этот модуль не прошел свои тесты установки с тех пор, как Perl 5.16 и ActiveState удалили его из удобного репозитория ppm (https://code.activestate.com/ppm/Win32-Unicode/).

К счастью, есть способ заставить его работать, так как 3 теста, которые не пройдены (относящиеся к «печати»), не используются для создания файла / каталога:

Шаг 1: ppm install dmake

Шаг 2: ppm install MinGW

Шаг 3: perl -MCPAN -e shell, затем force install Win32::Unicode

Шаг 1 и 2 обязательны, даже если на вашем компьютере уже установлена ​​Microsoft Visual Studio; очевидно, Perl теперь собран с MinGW, и модули тоже должны быть.

Уф.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...