|
-
Nov 3rd, 2005, 07:51 PM
#1
Thread Starter
Frenzied Member
Working with Unsigned integers.
Hi there,
I'm having some trouble working with UInt64 types. I don't WANT to work with the stupid things, but in this case, I'm trying to get the used disk space using the ManagementObject Class, and I can't figure out how to do this. I searched through MSDN a bit and found how to extract total size and free space, but with UInt64, you can't even do subtraction.. or convert it to any kind of variable that can do subraction. I can't even convert it to a string? How does anyone work with these variables?
Alternatively, If anyone knows a better way to get total disk space/free disk space/disk space used, I would appreciate that.
Bill
-
Nov 3rd, 2005, 08:13 PM
#2
Thread Starter
Frenzied Member
Re: Working with Unsigned integers.
Well, I managed to figure it out, but it's real ugly. Anyone got a better way?
VB Code:
Public Function GetDiskUsedSpaceInMB(ByVal driveletter As Char) As Integer
If (Char.ToUpper(driveletter) < "A") Or (Char.ToUpper(driveletter) > "Z") Then Return 0
Dim diskClass As _
New System.Management.ManagementClass("Win32_LogicalDisk")
Dim disks As System.Management.ManagementObjectCollection = diskClass.GetInstances()
Dim disk As System.Management.ManagementObject
Dim space As Long
For Each disk In disks
Dim diskname As String = Char.ToUpper(driveletter) + ":"
If CStr(disk("Name")) = diskname Then
space = Convert.ToInt64(CType(disk("Size"), UInt64)) - Convert.ToInt64(CType(disk("FreeSpace"), UInt64))
End If
Next disk
Dim SignedSpace As Int32 = Convert.ToInt32(Convert.ToInt64(space) \ 1048576) 'Divide by 1024^2, to convert bytes to Megabytes.
Return SignedSpace
End Function
I know I can convert UInt64 to Int64 if it's less than half the max value, and I'll add some exception handlers later.. But isn't there a better way?
Bill
-
Nov 3rd, 2005, 08:35 PM
#3
Re: Working with Unsigned integers.
So you're using the Win32_LogicalDisk class, and it's Size and FreeSpace properties? Are you trying to subtract FreeSpace from Size to get the used space? Try something like this:
VB Code:
Dim logicalDisks As New ManagementClass("Win32_LogicalDisk")
Dim totalSpace As Decimal
Dim freeSpace As Decimal
Dim usedSpace As Decimal
For Each logicalDisk As ManagementObject In logicalDisks.GetInstances()
totalSpace = New Decimal(CType(logicalDisk("Size"), UInt64))
freeSpace = New Decimal(CType(logicalDisk("FreeSpace"), UInt64))
usedSpace = totalspace - freeSpace
MessageBox.Show(String.Format("Drive: {1}{0}Capacity : {2} bytes{0}Used Space: {3} bytes{0}Free Space: {4} bytes", _
Environment.NewLine, _
logicalDisk("Name"), _
totalSpace, _
usedSpace, _
freeSpace))
Next logicalDisk
Note that the maximum value for a Decimal is 79,228,162,514,264,337,593,543,950,335 and for a UInt64 is 18,446,744,073,709,551,615 so there is no danger of the value being too big.
-
Nov 3rd, 2005, 08:37 PM
#4
Re: Working with Unsigned integers.
I was getting that together while you were posting again. Note that Decimal is the type to use because it is the only one that can be guaranteed to be big enough.
-
Nov 3rd, 2005, 08:48 PM
#5
Re: Working with Unsigned integers.
VB Code:
Public Function GetDiskUsedSpaceInMB(ByVal driveLetter As Char) As Integer
Dim logicalDisks As New ManagementClass("Win32_LogicalDisk")
Try
For Each logicalDisk As ManagementObject In logicalDisks.GetInstances()
If CStr(logicalDisk("Name")).Chars(0) = Char.ToUpper(driveLetter) Then
Dim totalSpace As New Decimal(CType(logicalDisk("Size"), UInt64))
Dim freeSpace As New Decimal(CType(logicalDisk("FreeSpace"), UInt64))
logicalDisk.Dispose()
Return Convert.ToInt32((totalSpace - freeSpace) / (1024 ^ 2))
End If
logicalDisk.Dispose()
Next logicalDisk
Finally
logicalDisks.Dispose()
End Try
Throw New Exception("Drive " & driveLetter & " does not exist.")
End Function
Note that I believe that in this case it is appropriate to throw an exception if the drive letter is invalid, as returning zero indicates that the drive exists but no space has been used.
Last edited by jmcilhinney; Nov 3rd, 2005 at 09:09 PM.
Reason: Removed redundant call to Math.Floor, added object disposal
-
Nov 3rd, 2005, 09:00 PM
#6
Re: Working with Unsigned integers.
As I've mentioned in another couple of threads recently, you can actually use the MgmtClassGen utility to automatically create .NET classes that directly correspond to WMI classes. This is probably more trouble than it's worth unless you want to re-use the class, but you could create a class that way and then give it additional properties or modify the ones is has to calculate the used space internally, then just get it with a single property access.
-
Nov 3rd, 2005, 09:26 PM
#7
Thread Starter
Frenzied Member
Re: Working with Unsigned integers.
 Originally Posted by jmcilhinney
VB Code:
Public Function GetDiskUsedSpaceInMB(ByVal driveLetter As Char) As Integer
Dim logicalDisks As New ManagementClass("Win32_LogicalDisk")
Try
For Each logicalDisk As ManagementObject In logicalDisks.GetInstances()
If CStr(logicalDisk("Name")).Chars(0) = Char.ToUpper(driveLetter) Then
Dim totalSpace As New Decimal(CType(logicalDisk("Size"), UInt64))
Dim freeSpace As New Decimal(CType(logicalDisk("FreeSpace"), UInt64))
logicalDisk.Dispose()
Return Convert.ToInt32((totalSpace - freeSpace) / (1024 ^ 2))
End If
logicalDisk.Dispose()
Next logicalDisk
Finally
logicalDisks.Dispose()
End Try
Throw New Exception("Drive " & driveLetter & " does not exist.")
End Function
Note that I believe that in this case it is appropriate to throw an exception if the drive letter is invalid, as returning zero indicates that the drive exists but no space has been used.
Well, I like the idea of throwing the exception, however.. isn't it impossible for a drive to have 0 used? Even with a freshly formatted disk drive you have the system volume information using up atleast a couple megabytes..
Bill
-
Nov 3rd, 2005, 09:35 PM
#8
Re: Working with Unsigned integers.
If you have a removable drive that has no media loaded then that code will return zero, because both Size and FreeSpace will be zero, so you should distinguish between a removable drive with no media loaded and a drive that doesn't exist. If you want to return a value that indicates an error then -1 would be more appropriate. Having said that, if you look at how the the .NET Framework normally works, throwing an exception is the most appropriate thing to do in that case. Have a look at how the IO functions behave when passed an invalid path. Frankly, the caller should be checking that a drive exists before calling your method, which is not difficult.
-
Nov 3rd, 2005, 09:53 PM
#9
Thread Starter
Frenzied Member
Re: Working with Unsigned integers.
Especially when the caller is me :P
I'll stick with the exception.
Bill
-
Nov 4th, 2005, 04:43 AM
#10
Re: Working with Unsigned integers.
This probably won't help you now but C# supports uints and soon VB2005 supports them fully too.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|