2

试图计算可能非常大的文件夹的大小,我使用了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 - $size\n";
}

我得到以下输出:

C:\$Recycle.Bin - 大小 C:\$Recycle.Bin:资源加载器在 olesize 第 22 行找不到 MUI 文件。
C:\引导 - 17463020
C:\cygwin - 1835711453
C:\戴尔 - 133184282
C:\doctemp - 12811140
C:\Documents and Settings - 大小 C:\Documents and Settings:资源加载器缓存在 olesize 第 22 行没有加载 MUI 条目。
C:\驱动程序 - 180746384
C:\eclipse - 324690795
C:\EFI - 262144
C:\found.000 - 大小 C:\found.000:资源加载器缓存在 olesize 第 22 行没有加载 MUI 条目。
C:\ghc - 1014658071
C:\gtk2hs - 138050118
C:\PerfLogs - 大小 C:\PerfLogs:资源加载器缓存在 olesize 第 22 行没有加载 MUI 条目。
C:\Perl - 115648300
C:\Program Files - 大小 C:\Program Files:资源加载器缓存在 olesize 第 22 行没有加载 MUI 条目。
C:\ProgramData - 大小 C:\ProgramData:资源加载器缓存在 olesize 第 22 行没有加载 MUI 条目。
C:\Python25 - 83902423
C:\System 卷信息 - 大小 C:\System 卷信息:资源加载器缓存在 olesize 第 22 行没有加载 MUI 条目。
C:\Users - 大小 C:\Users:资源加载器缓存在 olesize 第 22 行没有加载 MUI 条目。
C:\虚拟机 - 5401825804
C:\Windows - 大小 C:\Windows:资源加载器缓存在 olesize 第 22 行没有加载 MUI 条目。
C:\xampp - 408475320

这似乎至少部分是权限问题,因为以管理员身份运行代码会更改一些输出(以粗体表示)。

C:\$Recycle.Bin - 2062958143
C:\引导 - 17463020
C:\cygwin - 1835711453
C:\戴尔 - 133184282
C:\doctemp - 12811140
C:\Documents and Settings - 大小 C:\Documents and Settings:资源加载器在 olesize 第 22 行找不到 MUI 文件。
C:\驱动程序 - 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:资源加载器缓存在 olesize 第 22 行没有加载 MUI 条目。
C:\Python25 - 83902423
C:\System 卷信息 - 大小 C:\System 卷信息:资源加载器缓存在 olesize 第 22 行没有加载 MUI 条目。
C:\Users - 大小 C:\Users:资源加载器缓存在 olesize 第 22 行没有加载 MUI 条目。
C:\虚拟机 - 5401825804
C:\Windows - 大小 C:\Windows:资源加载器缓存在 olesize 第 22 行没有加载 MUI 条目。
C:\xampp - 408475320

MUI 错误消息对应于ERROR_MUI_FILE_NOT_FOUND.

我的代码怎么不正确?

对于上下文,我不需要使用FileSystemObject. 我考虑的其他方法是刮取dir /s子树中所有叶子的输出并将其大小相加。对于大型目录, 的输出dir /s可能是巨大的,并且搜索整个子树是一种性能狗。Windows 资源管理器似乎总是能够在给定足够的时间的情况下计算结果,那么有没有办法调用它正在做的任何事情?

4

1 回答 1

0

Another option is to stick to pure-perl: Filesys::DiskUsage does about the same thing. However, I'm betting that permission issues will remain. It should at least be better than scraping the output of dir /s.

To be honest, if Explorer works on these directories when you're not logged in as administrator, that seems like a privilege escalation issue in Explorer to me - apparently, Explorer can access the filesystem as if it were the administrator even when it isn't logged in as such, so if you can get your own DLL loaded by Explorer, you, too, could have admin access.

于 2011-04-23T20:27:58.447 回答