2 Attachment(s)
[VB6] Shell Drive Free Space
If you are using Shell objects there are lots of properties you can retrieve describing the filesystem and individual files. However the values returned are often types that VB is not prepared to cope with without some help.
Here we'll look at one of the Volume properties that gives you the capacity and free space for each drive in ssfDrives.
This program fetches the Drives Folder (ssfDrives) and retrieves the PKEY_Computer_DecoratedFreeSpace (as SCID_Computer_DecoratedFreeSpace).
The returned value is a PROPVARIANT, so we first convert it to a Variant for use in VB6.
The PROPVARIANT is empty or a "VT_VECTOR | VT_UI8" value, so if not empty we recast it as "VT_ARRAY | VT_CURRENCY" which is something we can play with in VB6.
Update:
It seems that VB6 can coerce these particular PROPVARIANTs to Variants itself. This saves an API call that isn't available in most pre-Vista Windows installations.
Then we format these values (1.) using normal techniques after scaling by 10000 to convert from our pseudo-Currency values to whole numbers, or (2.) by calling StrFormatByteSize() which produces abbreviated formats in KB, MB, GB, TB units.
You could probably also use PKEY_FreeSpace and PKEY_Capacity in separate calls of the ExtendedProperty() method, but I haven't tested that.
See the program comments: this code won't work before Vista except on XP SP2 or later with Windows Desktop Search (WDS) 3.0 or later installed. Those old systems do not have propsys.dll in them.
Update:
No longer a restriction.
Re: [VB6] Shell Drive Free Space
Warning:
If you compile this on Vista or Win7 (and probably Win8.x.y) the EXE will not run on XP, and most likely vice versa as well.
Microsoft broke binary compatibility on Shell32 automation classes between XP and Vista, so you'd need to rewrite the code to use late binding.
Re: [VB6] Shell Drive Free Space
You know, you could save yourself another API call by formatting the bytes to the suffixed form yourself:-
vb Code:
'
Private Function FormatSizeWithSuffix(ByVal size As Currency) As String
Dim i As Long
Dim denoms(0 To 4) As String
size = size * 10000@
denoms(0) = "Bytes"
denoms(1) = "KB"
denoms(2) = "MB"
denoms(3) = "GB"
denoms(4) = "TB"
For i = UBound(denoms) To 0 Step -1
Dim div As Currency
div = 1024 ^ i
If size > div Then
Dim val As Double
val = size / div
FormatSizeWithSuffix = Format(val, "0.##") + " " + denoms(i)
Exit Function
End If
Next
End Function
You can alter your code slightly to use like this:-
vb Code:
'
Private Function FormatByteSize(ByVal size As Currency) As String
'Size is really a UI8 here:
FormatByteSize = FormatSizeWithSuffix(size)
End Function
Not that your code is wrong or anything but I've always felt its better to avoid APIs if you can find a native implementation. That's just my personal opinion. Feel free to disregard.
Re: [VB6] Shell Drive Free Space
Forgot to mention, I never knew that Shell32.dll was also a COM server. I knew shell was COM based but never figured simply to try referencing Shell32.dll. Very interesting.
Re: [VB6] Shell Drive Free Space
True enough, that works fine. The only caveat is that when your disk drive is so big it uses bit 63 you'll have a problem. :p
People can always use alternatives, and the sample you gave may help them understand how to do other similar things. I was just trying to duplicate how Explorer does things: it really reports values in kibibytes, mebibytes, etc.
Re: [VB6] Shell Drive Free Space
Quote:
Originally Posted by
Niya
Forgot to mention, I never knew that Shell32.dll was also a COM server. I knew shell was COM based but never figured simply to try referencing Shell32.dll. Very interesting.
Yeah, it's only been able to do this since 1997 or so. It's covered in the MSDN Library docs that came with VB6.
Re: [VB6] Shell Drive Free Space
Quote:
Originally Posted by
dilettante
True enough, that works fine. The only caveat is that when your disk drive is so big it uses bit 63 you'll have a problem. :p
Yeah. I've always felt that the lack of unsigned types was a serious limitation of nearly all incarnations of BASIC. Still, one could probably do some kind of funky bit shifting and a little math to correct this potential problem.
Quote:
Originally Posted by
dilettante
According to that article, Kibibytes and its ilk are based on powers of 1024 whereas Kilobytes and such are based on 1000. I used 1024 in my implementation to match the output of the Windows shell.
Re: [VB6] Shell Drive Free Space
Just tried your version and I saw that. Sorry to be so dull today.