Sometimes you have to find disk drives of particular type. For example, you may have to search all removable disk drives or network mapped drives with VB.NET.
This sample shows how to check all drives and get their drive type, volume label and check if the drive is ready.
First, create a new standard WinForms project. Drop in a one button control and a one listbox control.
Import System.IO namespace
Imports System.IO
and then add the following declaration and helper procedure after form's declaration
Public Declare Function WNetGetConnection Lib "mpr.dll" Alias "WNetGetConnectionA" _ (ByVal lpszLocalName As String, ByVal lpszRemoteName As String, ByRef cbRemoteName As Integer) As Integer Public Function GetNetDriveName(ByVal DriveLetter As String) As String ' ' Return mapped drive UNC name Dim RetVal As Integer Dim OutName As String = New String(CChar(" "), 260) Dim NameLength As Integer = 260 Try RetVal = WNetGetConnection(DriveLetter, OutName, NameLength) OutName = OutName.Replace(Chr(0), " ").TrimEnd(CChar(" ")) Return OutName Catch ex As Exception Return "" End Try End Function
Mpr.dll is a Windows module which handles communication with installed networked providers. In this case its used in the helper function above to get UNC-name for mapped network drives.
Next is the actual procedure which loops drive letters and returns available information.
Public Sub GetDrives(ByRef DriveLetter() As String, ByRef VolumeLabel() As String, _ ByRef DriveTypeVal() As DriveType, ByRef PathToDrive() As String, _ ByRef IsDriveReady() As Boolean) ' ' Return available disc drives ' Const DRIVELETTERS As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" Dim Info As DriveInfo Dim Count As Integer Dim i As Integer Try Count = DRIVELETTERS.Length - 1 ReDim DriveLetter(Count) ReDim VolumeLabel(Count) ReDim DriveTypeVal(Count) ReDim PathToDrive(Count) ReDim IsDriveReady(Count) For i = 0 To Count DriveLetter(i) = DRIVELETTERS.Substring(i, 1) VolumeLabel(i) = "" DriveTypeVal(i) = DriveType.Unknown PathToDrive(i) = "" IsDriveReady(i) = False Next i For Each Info In My.Computer.FileSystem.Drives Count = DRIVELETTERS.IndexOf(Info.RootDirectory.FullName.Substring(0, 1)) DriveTypeVal(Count) = Info.DriveType If Info.IsReady Then IsDriveReady(Count) = True VolumeLabel(Count) = Info.VolumeLabel Else IsDriveReady(Count) = False VolumeLabel(Count) = "" End If If Info.DriveType = DriveType.Network Then PathToDrive(Count) = GetNetDriveName(DriveLetter(Count) & ":") Else PathToDrive(Count) = DriveLetter(Count) & ":" End If Next Info Catch ex As Exception ' Error handling End Try End Sub
And finally here's the code for Button1. The code call GetGrives-procedure and displays returned information in the ListBox1.
Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click ' ' Get drives and their types Dim DriveLetter() As String Dim VolumeLabel() As String Dim DriveTypeVal() As DriveType Dim PathToDrive() As String Dim IsDriveReady() As Boolean Dim TempStr As String Dim i As Integer Try ReDim DriveLetter(0) ReDim VolumeLabel(0) ReDim DriveTypeVal(0) ReDim PathToDrive(0) ReDim IsDriveReady(0) GetDrives(DriveLetter, VolumeLabel, DriveTypeVal, PathToDrive, IsDriveReady) ListBox1.Items.Clear() TempStr = "DriveLetter" & "; " TempStr = TempStr & "DriveType" & "; " TempStr = TempStr & "VolumeLabel" & "; " TempStr = TempStr & "PathToDrive" & "; " TempStr = TempStr & "IsDriveReady" ListBox1.Items.Add(TempStr) For i = 0 To DriveLetter.GetUpperBound(0) TempStr = DriveLetter(i) & "; " TempStr = TempStr & DriveTypeVal(i).ToString & "; " TempStr = TempStr & VolumeLabel(i) & "; " TempStr = TempStr & PathToDrive(i) & "; " TempStr = TempStr & IsDriveReady(i).ToString ListBox1.Items.Add(TempStr) Next i Catch ex As Exception ' Error handling End Try End Sub
The output looks something like this:
DriveLetter; DriveType; VolumeLabel; PathToDrive; IsDriveReady A; Removable; ; A:; False B; Unknown; ; ; False C; Fixed; ; C:; True D; Fixed; New Volume; D:; True E; CDRom; ; E:; False F; Fixed; HD-HCU2; F:; True G; Fixed; HD-HSU2; G:; True H; Fixed; MAXTOR; H:; True I; Removable; PORTABLEAPP; I:; True J; Unknown; ; ; False K; Unknown; ; ; False L; Unknown; ; ; False M; Unknown; ; ; False N; Unknown; ; ; False O; Unknown; ; ; False P; Unknown; ; ; False Q; Unknown; ; ; False R; Unknown; ; ; False S; Unknown; ; ; False T; Unknown; ; ; False U; Unknown; ; ; False V; Unknown; ; ; False W; Unknown; ; ; False X; Unknown; ; ; False Y; Unknown; ; ; False Z; Network; Vista; \\Cameron\Public; True
The listing shows that drive A is a removable disk but its not ready (it's a floppy disk drive). Drives C, D, F, G and H are hard disk drives and drive C has no volume label. Drive E is a CD/DVD drive and drive I is also a removable drive (USB memory stick). And finally drive Z is a network mapped drive.
What can you do and do not with this information? First, the only USB drive is drive I because drive letters A and B are assigned to floppy disks even if you do not have one. Second, drive Z's volume label is "Vista" in the PC from which it is shared. The share name is \\Cameron\Public so the server's name is "Cameron" and the shared folder is "Public".
And there's a few things you won't get with this code. First, only two of the five fixed disk drives are internal drives and three drives are external had disk drives, but you can't tell which. At least for sure. Second, drive E is of type "CDRom" but it is actually a writable CD/DVD combo drive. But again, you can't tell the difference with this code.
Do more with DriveInfo class
Now that you know how to get this information. you may experience other properties that DriveInfo class offers. Here's a list of a few interesting properties:
- Info.AvailableFreeSpace
- Info.DriveFormat
- Info.Name
- Info.TotalFreeSpace
- Info.TotalSize
Get drives of particular type with Visual Basic.NET
Here is a slight modification to the code above to make it more practical to use in VB.NET. This code gets the required drive type as parameter and returns only matching drives, if any. You may use this code to get only USB memory drives or network mapped drives for example.
Public Sub GetDrivesOfType(ByRef VolumeLabel() As String, _ ByRef PathToDrive() As String, ByRef IsDriveReady() As Boolean, _ ByVal DriveTypeVal As DriveType) ' ' Return drives of given type Dim Info As DriveInfo Dim ThisLetter As Char Dim Count As Integer Try Count = 0 For Each Info In My.Computer.FileSystem.Drives If Info.DriveType = DriveTypeVal Then ReDim Preserve VolumeLabel(Count) ReDim Preserve PathToDrive(Count) ReDim Preserve IsDriveReady(Count) ThisLetter = CChar(Info.RootDirectory.FullName.Substring(0, 1)) If Info.IsReady Then IsDriveReady(Count) = True VolumeLabel(Count) = Info.VolumeLabel Else IsDriveReady(Count) = False VolumeLabel(Count) = "" End If If Info.DriveType = DriveType.Network Then PathToDrive(Count) = GetNetDriveName(ThisLetter & ":") Else PathToDrive(Count) = ThisLetter & ":" End If Count += 1 End If Next Info Catch ex As Exception ' Error handling End Try End Sub
and you call this procedure:
ReDim VolumeLabel(0) ReDim PathToDrive(0) ReDim IsDriveReady(0) GetDrivesOfType(VolumeLabel, PathToDrive, IsDriveReady, DriveType.Removable)
to get all removable drives. If you want to get only USB memory sticks, remember that drives A and B are floppy disks. The output, if you use similar ListBox output as above, would look like this:
VolumeLabel; PathToDrive; IsDriveReady ; A:; False PORTABLEAPP; I:; True
So, the only USB stick drive would have a drive letter "I".