in reply to Windows Scriptin Host & OLE.

There are several sites on the web that have documentation on the WSH/FSO. The best one in terms of easy reference I found is FSO although it is a little light on worked examples.

The hardest part to wrap your brain around is how to access the elements of collections as returned by Win32::OLE. It's documentation is a little light on examples of using the in method.

In terms of your specific problem of getting a count of the files in a subtree. Unfortunately, there is no nice equivalent of the Size method that will return the count for the whole subtree, so you end up iterating the tree and totalling the file counts. Fortunately, each folder has a Count of the files it contains, so at least you dont have to iterate the files individually.

#! perl -slw use strict; use Win32::OLE qw[in]; my $fso = Win32::OLE->new( 'Scripting.FileSystemObject' ); my @folders = $fso->GetFolder( $ARGV[0] ); my $fCount =0; while( @folders ) { my $folder = pop @folders; $fCount += $folder->Files->Count; for my $subFolder ( in $folder->SubFolders ) { $fCount += $subFolder->Files->Count; push @folders, $_ for in $subFolder->SubFolders ; } } print $fCount;

Pleasingly, this renders the same answers as are shown on the Properties dialog for a subtree.

I haven't attempted to compare the performance of this with File::Find as previous attempts at this have be thwarted by the buffering issue. It seems to run fairly quickly though.


Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller

Replies are listed 'Best First'.
Re: Re: Windows Scriptin Host & OLE.
by Grygonos (Chaplain) on Jul 28, 2003 at 02:53 UTC
    this may not be what you're looking for. It doesn't use OLE, but unless WSH files and folders are different it should do the job with some modifications.

    This code takes a windows path and writes to c:\log.txt the contents of the given directory and all its subdirectories

    Please feel free to comment on this code as I'm sure its not perfect.
    #!/Perl/bin/perl use IO::File; use strict; print "Enter the directory to map: "; my $dir = <STDIN>; chomp($dir); my $log = new IO::File; $log->open(("> c:\\log.txt")) or die "$!"; $log->write("Map of: ".$dir,length("Map of: ".$dir)); $dir =~ s{\\}{\\\\}g; mapMe($dir); $log->close; ##Recursive routine to print out all the files & folders under a given + root node sub mapMe { #Get the parameter my $handle = shift; #Open the directory passed to the subroutine opendir(SPROUT,$handle); #read the entries my @entries = readdir(SPROUT); #Close the directory closedir(SPROUT); my $log_entry; #Start @ 2 to skip . & .. entries foreach my $i (2..scalar(@entries)) { #Format the handle for the next call my $param_handle = $handle."\\".$entries[$i]; #If its a directory and its not null if(opendir(TEST,$param_handle) and $entries[$i]) { #Close the directory closedir(TEST); #Strip the handle for log writing purposes $handle =~ s{\\\\}{\\}g; #Construct and write the log $log_entry = "\n".$handle."\\".$entries[$i]."\n"; $log->write($log_entry,length($log_entry)); #recurse the directory mapMe($param_handle); } elsif($entries[$i]) { #Construct and write the log $log_entry = "*".$entries[$i]."\n"; $log->write($log_entry,length($log_entry)); } } }
    I hope this will help you out.
Re: Re: Windows Scriptin Host & OLE.
by blackadder (Hermit) on Jul 28, 2003 at 10:05 UTC
    BrowserUK,....

    I could never thank you enough kind sir….

    But I can show my gratitude, for all your help, by donating few $$ to PerlMonks.

    Thanks a lot to all of you holly ones.
Re: Re: Windows Scriptin Host & OLE.
by blackadder (Hermit) on Jul 28, 2003 at 10:47 UTC
    $fcount return the number of files very nicely, but I couldn't see how I can return the number of folders. If I use the code supplied by bbfu
    my $file_count = $folder->Files()->Count(); my $folder_count = $folder->SubFolders()->Count(); my $total = $file_count + $folder_count; print "$file_count $folder_count $total \n";
    the results are not accurate because it only scans the top level of the path supplied!

    Do I need to recurs into every sub folder to get the number of folders or is there away that I can obtain the total number of folders (folders + subfolders) with this method?,...I am sure there is but the results I am getting are inaccurate....Your help is highly appreciated now I am so near finishing this thing off for good.

    Thanks Guys
      Ignore my previous post PLease....

      It was too simple I just needed to read your codes a little bit closer, Below is how I did it, it seems to be working

      Thanking you all.
      AUTOLOAD; require 5.006; $|++; use strict; use warnings 'all'; use diagnostics; use Win32::OLE qw[in]; my $fso = Win32::OLE->new( 'Scripting.FileSystemObject' ); my @folders = $fso->GetFolder( $ARGV[0] ); my $fCount =0; my $sCount =0; while( @folders ) { my $folder = pop @folders; $fCount += $folder->Files->Count; $sCount += $folder->SubFolders->Count; for my $subFolder ( in $folder->SubFolders ) { $fCount += $subFolder->Files->Count; push @folders, $_ for in $subFolder->SubFolders ; $sCount += $subFolder->SubFolders->Count; } } print "Files : $fCount, folders : $sCount\n";
      Aaaaouch, Lost a point and that really hurts...Well losing points here on PerlMonks is helping me to be less lazy...

      Great Spirits have always encountered violent opposition from mediocre minds. ******************************************************************