#windows #perl #win32ole #windows-scripting #filesystemobject
#Windows #perl #win32ole #windows-скриптинг #filesystemobject
Вопрос:
Пытаясь вычислить размер папки, который мог бы быть очень большим, я использовал FileSystemObject.Size
:
#! perl
use strict;
use warnings;
use 5.10.0;
use File::Spec;
use Win32::OLE;
my $_fso;
sub folder_size {
my($folder) = @_;
$_fso = Win32::OLE->new("Scripting.FileSystemObject")
unless defined $_fso;
die "GetFolder $folder: $^E"
unless defined(my $f = $_fso->GetFolder($folder));
my $size = $f->Size;
die "Size $folder: $^E" unless defined $size;
$size;
}
В некоторых случаях folder_size
возвращается нормально, но в других вызов Size
вызывает исключения. Вычисление размеров папок в C:
с
my $root = "C:/";
opendir my $dh, $root or die "$0: opendir: $!";
while (defined(my $name = readdir $dh)) {
next if $name eq "." || $name eq "..";
my $folder = File::Spec->catdir($root, $name);
next unless -d $folder;
chomp(my $size = eval { folder_size $folder } // $@);
print "$folder - $sizen";
}
Я получаю следующий вывод:
C: $Recycle.Размер ячейки C: $ Recycle.Bin: загрузчику ресурсов не удалось найти MUI-файл в строке 22 olesize. C:boot - 17463020 C:cygwin - 1835711453 C:DELL - 133184282 C:doctemp - 12811140 C:Documents и настройки - Размер C:Documents и настройки: в кэше загрузчика ресурсов нет записи loaded MUI в строке olesize 22. C:Drivers - 180746384 C:eclipse - 324690795 C:EFI - 262144 C:found.000 - Размер C:found.000: В кэше загрузчика ресурсов нет записи loaded MUI в строке 22 olesize. C:ghc - 1014658071 C:gtk2hs - 138050118 C:PerfLogs - Размер C:PerfLogs : В кэше загрузчика ресурсов нет записи loaded MUI в строке 22 olesize. C:Perl - 115648300 C:Program Файлы - Размер C:Program Файлы: В кэше загрузчика ресурсов нет записи loaded MUI в строке 22 olesize. C:ProgramData - Размер C:ProgramData : В кэше загрузчика ресурсов нет записи loaded MUI в строке 22 olesize. C:Python25 - 83902423 C:System Информация о томе - Размер C:System Информация об объеме: в кэше загрузчика ресурсов нет записи loaded MUI в строке 22 olesize. C:Users - Размер C:Users : В кэше загрузчика ресурсов нет записи loaded MUI в строке 22 olesize. C:Virtual Компьютеры - 5401825804 C:Windows - Размер C:Windows : В кэше загрузчика ресурсов нет записи loaded MUI в строке 22 olesize. C:xampp - 408475320
Похоже, что это, по крайней мере частично, проблема с разрешениями, потому что запуск кода от имени администратора изменяет часть выходных данных (выделено жирным шрифтом).
C:$Recycle.Bin - 2062958143 C:boot - 17463020 C:cygwin - 1835711453 C:DELL - 133184282 C:doctemp - 12811140 C:Documents и настройки - Размер C:Documents и настройки: загрузчику ресурсов не удалось найти MUI-файл в строке olesize 22. C:Drivers - 180746384 C:eclipse - 324690795 C:EFI - 262144 C:found.000 - 8950 C:ghc - 1014658071 C:gtk2hs - 138050118 C:PerfLogs - 0 C:Perl - 115648300 C:Program Файлы - 10857194364 C:ProgramData - Размер C:ProgramData : В кэше загрузчика ресурсов нет записи loaded MUI в строке 22 olesize. C:Python25 - 83902423 C:System Информация о томе - Размер C:System Информация об объеме: в кэше загрузчика ресурсов нет записи loaded MUI в строке 22 olesize. C:Users - Размер C:Users : В кэше загрузчика ресурсов нет записи loaded MUI в строке 22 olesize. C:Virtual Компьютеры - 5401825804 C:Windows - Размер C:Windows : В кэше загрузчика ресурсов нет записи loaded MUI в строке 22 olesize. C:xampp - 408475320
Сообщение об ошибке MUI соответствует ERROR_MUI_FILE_NOT_FOUND
.
Почему мой код неверен?
Что касается контекста, у меня нет никаких требований к использованию FileSystemObject
. Другими подходами, которые я рассматривал, были очистка выходных данных dir /s
и суммирование размеров всех листьев в поддереве. Для больших каталогов выходные данные dir /s
могут быть огромными, а очистка всего поддерева — это контроль производительности. Кажется, что проводник Windows всегда может вычислить результат за достаточное время, так есть ли способ вызвать то, что он делает?
Комментарии:
1. Я подозреваю, что Explorer просто игнорирует исключения. Что произойдет, если вы попытаетесь измерить одну из папок, которая получает исключение, с помощью Explorer?
2. у @cjm Explorer нет никаких проблем с
C:Program Files
илиC:Windows
: размер в таблице свойств устанавливается при ответе в течение 30 секунд. Заполнение глубины каталогов с помощью File::Find занимает как минимум в 5 раз больше времени.
Ответ №1:
Другой вариант — придерживаться чистого perl: Filesys::DiskUsage делает примерно то же самое. Однако я готов поспорить, что проблемы с разрешениями останутся. Это должно быть, по крайней мере, лучше, чем очистка выходных данных dir /s
.
Честно говоря, если Explorer работает с этими каталогами, когда вы не вошли в систему как администратор, мне кажется, что это проблема с повышением привилегий в Explorer — по-видимому, Explorer может получить доступ к файловой системе, как если бы он был администратором, даже когда он не вошел в систему как таковой, поэтому, если вы можете загрузить свою собственную DLL с помощью Explorer, вы тоже можете иметь доступ администратора.