Логическая ошибка в:
my $dir = $wdir->open($dir) || die $wdir->error;
my $dir_complete = "$dir/a.txt";
$wdir->open('path') возвращает объект, а не строку. Вы не можете использовать его как путь. Но это не самое худшее. К сожалению, похоже, что реализация Tk еще не поддерживает имена файлов Unicode (включая ChooseDirectory). Я думаю, вам придется написать собственный селектор каталогов, но я не уверен, что это вообще возможно.
Это способно отображать файлы в папке ascii-chars (а ->fetch может отображать файлы utf-8) и аварийно завершает работу при открытии папки с символами utf-8. Ну, честно говоря, он вылетает при открытии ??????.
use strict;
use warnings;
use Win32::Unicode::Dir;
use Win32::Unicode::Console;
use Encode;
use Tk;
my $mw = Tk::MainWindow->new;
my $tissue_but = $mw->Button(
-text => 'Select dir',
-command => [ \&select_unicode_directory ],
);
$tissue_but->grid( -row => 3, -column => 1 );
Tk::MainLoop();
sub select_unicode_directory {
my $wdir = Win32::Unicode::Dir->new;
my $selected = $mw->chooseDirectory(-parent =>$mw);
# http://search.cpan.org/dist/Tk/pod/chooseDirectory.pod#CAVEATS
$selected = encode("utf-8", $selected);
print "selected: $selected\n";
$wdir->open($selected) || die $wdir->error;
print "\$mw->chooseDirectory: $selected\n";
print "\$wdir->open(\$selected): $wdir\n";
# CRASH HERE, presumably because winders can't handle '?' in a file (dir) name
for ($wdir->fetch) {
# http://search.cpan.org/~xaicron/Win32-Unicode-0.38/lib/Win32/Unicode/Dir.pm
next if /^\.{1,2}$/;
my $path = "$selected/$_";
if (file_type('f', $path)) { print "file: $path\n"; }
elsif (file_type('d', $path)) { print " dir: $path\n"; }
}
print "closing \n";
$wdir->close || die $wdir->error;
}
Вывод образца (открытие Поиск/):
Оба приведенных ниже примера были запущены с использованием: Strawberry Perl 5.12.3, созданного для MSWin32-x64-multi-thread.
selected: C:/cygwin/home/jaroslav/tmp/so/perl/open-file-tk/?????
$mw->chooseDirectory: C:/cygwin/home/jaroslav/tmp/so/perl/open-file-tk/?????
$wdir->open($selected): Win32::Unicode::Dir=HASH(0x2e38158)
>>> perl crash <<<
Образец (открывающий родитель Поиска):
selected: C:/cygwin/home/jaroslav/tmp/so/perl/open-file-tk
$mw->chooseDirectory: C:/cygwin/home/jaroslav/tmp/so/perl/open-file-tk
$wdir->open($selected): Win32::Unicode::Dir=HASH(0x2b92c10)
file: C:/cygwin/home/jaroslav/tmp/so/perl/open-file-tk/.select_uni_dir.pl.swp
file: C:/cygwin/home/jaroslav/tmp/so/perl/open-file-tk/o
file: C:/cygwin/home/jaroslav/tmp/so/perl/open-file-tk/o.dir
file: C:/cygwin/home/jaroslav/tmp/so/perl/open-file-tk/select_uni_dir.pl
file: C:/cygwin/home/jaroslav/tmp/so/perl/open-file-tk/select_uni_file.pl
dir: C:/cygwin/home/jaroslav/tmp/so/perl/open-file-tk/Поиск
Заключение
Селектор Tk dir возвращает ????? вместо Поиск. Ища способ включить Unicode в Tk, я нашел это:
http://search.cpan.org/dist/Tk/pod/UserGuide.pod#Perl/Tk_and_Unicode :
(...) К сожалению, в Perl все еще есть места, не знающие Unicode. Одним из таких мест являются имена файлов. Следовательно, селекторы файлов в Perl/Tk неправильно обрабатывают кодировку имен файлов. В настоящее время они предполагают, что имена файлов имеют кодировку iso-8859-1, по крайней мере, в системах Unix. Как только в Perl появится концепция кодирования имен файлов, Perl/Tk также будет реализовывать такие схемы.
Итак, на первый взгляд кажется, что то, что вы пытаетесь сделать, невозможно (если вы не напишете или не найдете собственный селектор каталогов). На самом деле, может быть неплохо сообщить об этой ошибке, потому что графический интерфейс отображал "Поиск", так что ошибка в возвращаемом значении.
person
Ярослав Рахматуллин
schedule
29.07.2013
openзанимает байты. ИспользуйтеCreateFileWWin32API::File, чтобы открыть файл. IIRC, вам придется сначала пройти черезencode('UTF-16le', "$qfn\0"). - person ikegami   schedule 28.06.2013