Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Size on disk (compressed)

143 views
Skip to first unread message

Claude Lachapelle

unread,
Nov 28, 2007, 1:50:00 PM11/28/07
to
Still unanswered -- any way in VBScript to get this information
(getfoldersize)?

Thanks.

Claude Lachapelle
Systems Administrator, MCSE

rusga

unread,
Nov 29, 2007, 11:26:46 AM11/29/07
to
Would you be so kind to post me when you get an answer please? Thank you.

rusga
Rockstar

"Claude Lachapelle" <ClaudeLa...@discussions.microsoft.com> wrote in
message news:F79D03A2-AF42-4A3B...@microsoft.com...

Tom Lavedas

unread,
Nov 29, 2007, 3:52:08 PM11/29/07
to
On Nov 29, 11:26 am, "rusga" <only@newsgroup> wrote:
> Would you be so kind to post me when you get an answer please? Thank you.
>
> rusga
> Rockstar
>
> "Claude Lachapelle" <ClaudeLachape...@discussions.microsoft.com> wrote in
> messagenews:F79D03A2-AF42-4A3B...@microsoft.com...

>
> > Still unanswered -- any way in VBScript to get this information
> > (getfoldersize)?
>
> > Thanks.
>
> > Claude Lachapelle
> > Systems Administrator, MCSE

The reason there has been so much silence on this subject is that
there is no easy way to get this information in script. Not even WMI
provides a way to determine this data. My searches turned up a number
of references to a system API call, which is tough to do in script, or
a suggestion to compute the number from file and allocation unit
sizes, but without a specific way to do it.

I'm not into API calls, though there are some third party applications
that make it possible, I guess - oh, and I remember one example of
doing it using VBA in an Office application, like Excel. But that
seems like using a sludge hammer to swat a fly, both unwieldy and
overkill.

So, I approached the problem as a puzzle to be solved using the
computation approach. To do this, I needed the compressed file size
and the allocation unit size. Neither is easy to come by. I finally
found an intrinsic command line utility (in XP at least) called
COMPACT.exe that returns the compacted file size, but can not think of
a practical means of determining the allocation unit size. It can be
had from the CHKDSK utility for a floppy (what are those, you ask) or
hard drive, but it is extremely slow for hard drives and can't be
applied to some other media, such as a CD. So, I am going to leave
that to others. I just assume the standard 4096 byte cluster size of
a common NTFS disk installation in the solution shown below ...

'-------------------8<------------------
Const AllocationUnitSize = 4096 ' bytes

sFileSpec = ".\*" ' current folder, for example

sCmd = "compact " & sFileSpec & " | find "" = """
aFiles = CmdPrompt(sCmd)
nSizeonDisk = 0
For each anItem in aFiles
if trim(anItem) <> "" then
nFileSize = Split(Replace(Replace(anItem, " ", "")_
,"=", ":"), ":")(1)
nUnits = nFileSize \ AllocationUnitSize
if nFileSize Mod AllocationUnitSize > 0 then _
nUnits = nUnits + 1
nSizeonDisk = nSizeonDisk _
+ nUnits * AllocationUnitSize
End If
next
wsh.echo "Size on Disk:", nSizeonDisk

Function CmdPrompt(sCmd)
Dim alines, sCmdLine, stemp, ofs, oWS, nRes
'On Error Resume Next
sCmdLine = """%comspec%"" /c " & sCmd & " >> "
set ofs = CreateObject("Scripting.FileSystemObject")
stemp = ofs.GetTempName
set oWS = CreateObject("Wscript.Shell")
stemp = oWS.Environment("PROCESS")("TEMP") & "\" & stemp
nRes = oWS.Run(sCmdLine & Chr(34) & sTemp & Chr(34) & " 2>>&1" _
, 0, True)
'alines = "ERRORLEVEL: " & nRes & vbCRLF
if ofs.FileExists(sTemp) Then
with ofs.OpenTextFile(stemp)
if Not .AtEndofStream Then
alines = aLines & .ReadAll
End if
End With
ofs.DeleteFile stemp
alines = Split(aLines, vbNewline)
Else
aLines = Array(nRes, "")
End if
ReDim Preserve alines(Ubound(alines) - 1)
if Err.Number <> 0 Then _
aLines = Array("Error Number:" & CStr(Err.Number),
Err.Description)
CmdPrompt = alines
End Function
'-------------------8<------------------

A file name or wildcard filespec is provided for the search as well as
an allocation unit size, if it differs from the standard I used. For
example, to size the contents of a folder named 'c:\Test', the
filespec would be 'c:\Test\*'.

My quick tests gave the same results as the folder Properties 'Size on
disk' in explorer for a couple of compressed folder and an
uncompressed one, as well.

I hope this serves. It's the best I could figure out.

Tom Lavedas
===========
http://members.cox.net/tglbatch/wsh/

Claude Lachapelle

unread,
Nov 29, 2007, 5:54:05 PM11/29/07
to
Beautiful!

Thanks a lot Tom!

mr_unreliable

unread,
Nov 30, 2007, 4:55:13 PM11/30/07
to
Tom Lavedas wrote:
> The reason there has been so much silence on this subject is that
> there is no easy way to get this information in script. Not even WMI
> provides a way to determine this data. My searches turned up a number
> of references to a system API call, which is tough to do in script, or
> a suggestion to compute the number from file and allocation unit
> sizes, but without a specific way to do it.
>

The api that Tom must have seen is "GetCompressedFileSize" which
is a relatively simple api, and probably could be called using
Dynawrap.

http://msdn2.microsoft.com/en-us/library/aa364930.aspx

If calling api's from script is too much for anybody, or is
morally offensive, then is is possible it write an actX dll/ocx
to do the job, in any language that supports actX and api calls.
In the old days, the "usual suspect" was microsoft's free (gasp!)
vb5cce compiler. Unfortunately, microsoft has withdrawn vb5cce
from distribution. Fortunately, it can still be found elsewhere,
such as:

http://www.thevbzone.com/vbcce.htm
http://www.vbcodesource.org/downloads/software/vb5cce.zip

And if using DynaWrap, or writing your own actX object to call
the system api is STILL too much, then you could use some other
scripting language that DOES support api calls. Here are two:

AutoIt3: http://www.autoitscript.com/autoit3/
FBSL: http://www.fbsl.net/phpbb2/index.php

cheers, jw
____________________________________________________________

You got questions? WE GOT ANSWERS!!! ..(but,
no guarantee the answers will be applicable to the questions)


--- <DynaWrap Boilerplate> ---
It is possible to declare-and-call an api from script,
but you must use a third-party control to do so,
or else write one yourself.

It has already been correctly pointed out that there
is no api-capability in "pure" script.

If you are willing to use a third-party control, then
one such control, called "DynaWrap", can be found on
Guenter Born's website (note: Guenter refers to it as
"DynaCall"). Here is the link to it:

http://people.freenet.de/gborn/WSHBazaar/WSHDynaCall.htm

- or, alternatively -

http://ourworld.compuserve.com/homepages/Guenter_Born/WSHBazaar/WSHDynaCall.htm

On that page you will find a download for the control,
plus some code samples.

Note: you may find additional sample code by searching
the archives of the wsh and vbscript ng's.

Note also: DynaWrap does have its limitations. There are
certain things it can't do. For example, you can't call
api's "by ordinal". (I had previously asserted that you
can't use DynaWrap to call api's which take typedefs as
parameters, but I have been proven wrong on that --
although it took me about two weeks to figure out how it
was done). Regardless, Dynawrap will work for most of
"the usual suspects".

And finally, DynaWrap doesn't work entirely as advertised.
For example, it is supposed to allow for the declaration of
several api definitions in one instance of itself. I could
never get that to work (in win9x -- but others have shown
this to work as advertised under winNT). With win98, you
will need a new instance of DynaWrap for every api, or else
re-instantiate the object for every api. Someday I'm going
to learn enough c++ to fix that...
--- </DynaWrap Boilerplate> ---

0 new messages