Introduction
Have you ever needed to know how many hard disks there are in the computer your app is running on? Which partitions are on which hard disks?
Which drives are network drives, and what their UNC paths may be? What the dos name and number of the CD/DVDRoms in the system may be?
In this example project you will find the class clsDiskInfoEx
- which is a compilation of code I use to accomplish these ends.
This code runs correctly on Windows 7, Vista, 2003 and XP.
Background
Recently I've been working on code to accomplish faster file copies in Windows. There are some 3rd party utilities, I know - but I wanted to be able to integrate this
into my code. Eventually I found myself trying to figure out why concurrent reading and writing sometimes slowed things down. A little searching
revealed the ugly truth - that reading and writing to the same hard drive concurrently was the problem. I set about trying to figure out which
partitions were on the same hard drive to compensate, and this class was the result.
This code was not entirely written by me - jo0l's
.NET stuff and pinvoke.net were great starting points, and if you haven't already you should check them out.
Using the code
clsDiskInfoEx
does quite a bit behind the scene, and has several useful methods. Instantiate it with new the way you normally would with any class.GetNetworkComputers
- Returns a list(Of String)
of the available computers in your network.GetNetworkDrives
- Returns a list(Of String)
of network drives and their
UNC paths, separated by "=".GetUncPathOfMappedDrive
- I think this is self explanatory.GetPhysicalDisks
- returns a list(Of String)
of all the drives in the system and their respective parent device, be it an Physical disk, UNC path or dos CD Rom number formatted as follows: "C:=\\.\PhysicalDisk0"GetPhysicalDiskParentFor(logicalDisk As String) As String
- This is the one that gets all the use in this example project.
When you instantiate the class, it fills an internal list with information about all the drives in your system. Feed this method the root directory
of a drive (i.e.: "c:\") and it gives you the parent drive for that partition. To update the disk information (i.e.: someone plugged
in a flash drive or inserted a CD), use the Refresh()
method.
Here's a quick look at the code that adds the drive information into a listview in the example project's main form:
Private Sub GetDriveInfo()
Dim count As Int32 = 0
Dim driveInfoEx As New clsDiskInfoEx
Dim multipleParents() As String = Nothing
Dim parentDrives As String = Nothing
lvDriveInfo.Items.Clear()
For Each drive As System.IO.DriveInfo In System.IO.DriveInfo.GetDrives
parentDrives = driveInfoEx.GetPhysicalDiskParentFor(drive.RootDirectory.ToString)
If parentDrives.Contains(", ") Then
multipleParents = Split(parentDrives, ", ")
For more As Int32 = (multipleParents.Length - 1) To 0 Step -1
If more = (multipleParents.Length - 1) Then
lvDriveInfo.Items.Add("")
lvDriveInfo.Items(count).SubItems.Add(drive.RootDirectory.ToString.Replace("\", ""))
lvDriveInfo.Items(count).SubItems.Add(multipleParents(more))
lvDriveInfo.Items(count).SubItems.Add(drive.DriveType.ToString)
If drive.IsReady Then
lvDriveInfo.Items(count).SubItems.Add(drive.DriveFormat)
lvDriveInfo.Items(count).SubItems.Add((drive.TotalSize / 1000000).ToString("N0") & " MB")
lvDriveInfo.Items(count).SubItems.Add((drive.AvailableFreeSpace / 1000000).ToString("N0") & " MB")
Else
lvDriveInfo.Items(count).SubItems.Add("No Disc")
lvDriveInfo.Items(count).SubItems.Add("-")
lvDriveInfo.Items(count).SubItems.Add("-")
End If
Else
count += 1
lvDriveInfo.Items.Add("")
lvDriveInfo.Items(count).SubItems.Add(drive.RootDirectory.ToString.Replace("\", ""))
lvDriveInfo.Items(count).SubItems.Add(multipleParents(more))
lvDriveInfo.Items(count).SubItems.Add("Mirror or Span")
If drive.IsReady Then
lvDriveInfo.Items(count).SubItems.Add(drive.DriveFormat)
Else
lvDriveInfo.Items(count).SubItems.Add("")
End If
lvDriveInfo.Items(count).SubItems.Add("-")
lvDriveInfo.Items(count).SubItems.Add("-")
End If
Next
count += 1
Else
lvDriveInfo.Items.Add("")
lvDriveInfo.Items(count).SubItems.Add(drive.RootDirectory.ToString.Replace("\", ""))
lvDriveInfo.Items(count).SubItems.Add(parentDrives)
lvDriveInfo.Items(count).SubItems.Add(drive.DriveType.ToString)
If drive.IsReady Then
lvDriveInfo.Items(count).SubItems.Add(drive.DriveFormat)
lvDriveInfo.Items(count).SubItems.Add((drive.TotalSize / 1000000).ToString("N0") & " MB")
lvDriveInfo.Items(count).SubItems.Add((drive.AvailableFreeSpace / 1000000).ToString("N0") & " MB")
Else
lvDriveInfo.Items(count).SubItems.Add("No Disc")
lvDriveInfo.Items(count).SubItems.Add("-")
lvDriveInfo.Items(count).SubItems.Add("-")
End If
count += 1
End If
Next
End Sub
Points of Interest
This class also correctly reports partitions that span drives, like mirrors, stripes or spanned volumes. However, it has only been tested in a machine
with mirrored drives. If it behaves badly in systems with alternate configurations, I'd love to know it.