Results 1 to 10 of 10

Thread: Working with Unsigned integers.

  1. #1

    Thread Starter
    Frenzied Member conipto's Avatar
    Join Date
    Jun 2005
    Location
    Chicago
    Posts
    1,175

    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
    Hate Adobe Acrobat? My Codebank Sumbissions - Easy CodeDom Expression evaluator: (VB / C# ) -- C# Scrolling Text Display

    I Like to code when drunk. Don't say you weren't warned.

  2. #2

    Thread Starter
    Frenzied Member conipto's Avatar
    Join Date
    Jun 2005
    Location
    Chicago
    Posts
    1,175

    Re: Working with Unsigned integers.

    Well, I managed to figure it out, but it's real ugly. Anyone got a better way?

    VB Code:
    1. Public Function GetDiskUsedSpaceInMB(ByVal driveletter As Char) As Integer
    2.         If (Char.ToUpper(driveletter) < "A") Or (Char.ToUpper(driveletter) > "Z") Then Return 0
    3.         Dim diskClass As _
    4.             New System.Management.ManagementClass("Win32_LogicalDisk")
    5.         Dim disks As System.Management.ManagementObjectCollection = diskClass.GetInstances()
    6.         Dim disk As System.Management.ManagementObject
    7.         Dim space As Long
    8.         For Each disk In disks
    9.             Dim diskname As String = Char.ToUpper(driveletter) + ":"
    10.             If CStr(disk("Name")) = diskname Then
    11.                 space = Convert.ToInt64(CType(disk("Size"), UInt64)) - Convert.ToInt64(CType(disk("FreeSpace"), UInt64))
    12.             End If
    13.         Next disk
    14.         Dim SignedSpace As Int32 = Convert.ToInt32(Convert.ToInt64(space) \ 1048576) 'Divide by 1024^2, to convert bytes to Megabytes.
    15.         Return SignedSpace
    16. 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
    Hate Adobe Acrobat? My Codebank Sumbissions - Easy CodeDom Expression evaluator: (VB / C# ) -- C# Scrolling Text Display

    I Like to code when drunk. Don't say you weren't warned.

  3. #3
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    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:
    1. Dim logicalDisks As New ManagementClass("Win32_LogicalDisk")
    2.         Dim totalSpace As Decimal
    3.         Dim freeSpace As Decimal
    4.         Dim usedSpace As Decimal
    5.  
    6.         For Each logicalDisk As ManagementObject In logicalDisks.GetInstances()
    7.             totalSpace = New Decimal(CType(logicalDisk("Size"), UInt64))
    8.             freeSpace = New Decimal(CType(logicalDisk("FreeSpace"), UInt64))
    9.             usedSpace = totalspace - freeSpace
    10.  
    11.             MessageBox.Show(String.Format("Drive: {1}{0}Capacity : {2} bytes{0}Used Space: {3} bytes{0}Free Space: {4} bytes", _
    12.                                           Environment.NewLine, _
    13.                                           logicalDisk("Name"), _
    14.                                           totalSpace, _
    15.                                           usedSpace, _
    16.                                           freeSpace))
    17.         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.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    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.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  5. #5
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    Re: Working with Unsigned integers.

    VB Code:
    1. Public Function GetDiskUsedSpaceInMB(ByVal driveLetter As Char) As Integer
    2.         Dim logicalDisks As New ManagementClass("Win32_LogicalDisk")
    3.  
    4.         Try
    5.             For Each logicalDisk As ManagementObject In logicalDisks.GetInstances()
    6.                 If CStr(logicalDisk("Name")).Chars(0) = Char.ToUpper(driveLetter) Then
    7.                     Dim totalSpace As New Decimal(CType(logicalDisk("Size"), UInt64))
    8.                     Dim freeSpace As New Decimal(CType(logicalDisk("FreeSpace"), UInt64))
    9.  
    10.                     logicalDisk.Dispose()
    11.  
    12.                     Return Convert.ToInt32((totalSpace - freeSpace) / (1024 ^ 2))
    13.                 End If
    14.  
    15.                 logicalDisk.Dispose()
    16.             Next logicalDisk
    17.         Finally
    18.             logicalDisks.Dispose()
    19.         End Try
    20.  
    21.         Throw New Exception("Drive " & driveLetter & " does not exist.")
    22.     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
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  6. #6
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    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.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  7. #7

    Thread Starter
    Frenzied Member conipto's Avatar
    Join Date
    Jun 2005
    Location
    Chicago
    Posts
    1,175

    Re: Working with Unsigned integers.

    Quote Originally Posted by jmcilhinney
    VB Code:
    1. Public Function GetDiskUsedSpaceInMB(ByVal driveLetter As Char) As Integer
    2.         Dim logicalDisks As New ManagementClass("Win32_LogicalDisk")
    3.  
    4.         Try
    5.             For Each logicalDisk As ManagementObject In logicalDisks.GetInstances()
    6.                 If CStr(logicalDisk("Name")).Chars(0) = Char.ToUpper(driveLetter) Then
    7.                     Dim totalSpace As New Decimal(CType(logicalDisk("Size"), UInt64))
    8.                     Dim freeSpace As New Decimal(CType(logicalDisk("FreeSpace"), UInt64))
    9.  
    10.                     logicalDisk.Dispose()
    11.  
    12.                     Return Convert.ToInt32((totalSpace - freeSpace) / (1024 ^ 2))
    13.                 End If
    14.  
    15.                 logicalDisk.Dispose()
    16.             Next logicalDisk
    17.         Finally
    18.             logicalDisks.Dispose()
    19.         End Try
    20.  
    21.         Throw New Exception("Drive " & driveLetter & " does not exist.")
    22.     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
    Hate Adobe Acrobat? My Codebank Sumbissions - Easy CodeDom Expression evaluator: (VB / C# ) -- C# Scrolling Text Display

    I Like to code when drunk. Don't say you weren't warned.

  8. #8
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    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.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  9. #9

    Thread Starter
    Frenzied Member conipto's Avatar
    Join Date
    Jun 2005
    Location
    Chicago
    Posts
    1,175

    Re: Working with Unsigned integers.

    Especially when the caller is me :P

    I'll stick with the exception.

    Bill
    Hate Adobe Acrobat? My Codebank Sumbissions - Easy CodeDom Expression evaluator: (VB / C# ) -- C# Scrolling Text Display

    I Like to code when drunk. Don't say you weren't warned.

  10. #10
    type Woss is new Grumpy; wossname's Avatar
    Join Date
    Aug 2002
    Location
    #!/bin/bash
    Posts
    5,682

    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
  •  



Click Here to Expand Forum to Full Width