Introduction
Getting information about logical drives might not be an easy task. Using managed code, one way to do this is by using the System.Management
namespace.
Background
In order to create something reusable, I have wrapped this functionality in a DiskCollection
class derived from CollectionBase
. This collection acts as a class factory to create instances of a nested class called LogicalDriveInfo
. Two indexers, one using the order and the other the drive letter will provide the read only information about the drives.
public LogicalDriveInfo this[int i]
{
get
{
if(i >= disks.Count || i < 0)
return null;
else
return (LogicalDriveInfo)disks[i];
}
}
public LogicalDriveInfo this[char drive]
{
get
{
if(char.IsLetter(drive))
foreach(LogicalDriveInfo drinfo in disks)
if(char.ToLower(drinfo.Name) == char.ToLower(drive))
return drinfo;
return null;
}
}
But the work horse of this collection is the Load()
method that gets the information from the ManagementObject
instances. Using two queries that target the mapped and the local disks, the disk's ArrayList
is populated with LogicalDriveInfo
instances.
using(ManagementObjectSearcher DiskSearch =
new ManagementObjectSearcher(new
SelectQuery("Select * from Win32_LogicalDisk")))
{
using(ManagementObjectCollection moDiskCollection =
DiskSearch.Get())
{
foreach(ManagementObject mo in moDiskCollection)
{
LogicalDriveInfo dskinfo =
new LogicalDriveInfo(mo ,false);
if(this[dskinfo.Name] == null)
disks.Add(dskinfo);
mo.Dispose();
}
}
}
using(ManagementObjectSearcher ShareDiskSearch =
new ManagementObjectSearcher(new
SelectQuery("Select * from Win32_MappedLogicalDisk")))
{
using(ManagementObjectCollection moSharedDiskCollection =
ShareDiskSearch.Get())
{
foreach(ManagementObject mo in moSharedDiskCollection)
{
LogicalDriveInfo dskinfo = new LogicalDriveInfo(mo ,true);
if(this[dskinfo.Name] == null)
{
disks.Add(dskinfo);
}
else
this[dskinfo.Name].Shared = true;
mo.Dispose();
}
}
}
You should be aware of the fact that you would need certain privileges to iterate the mapped disk collection. Another thing worth noting is the way we extract the information from the ManagementObject
using an indexer:
internal LogicalDriveInfo(ManagementObject mo, bool shared)
{
try
{
string txt = mo["Name"].ToString();
if(txt.Length > 0)
Name = txt[0];
txt = mo["Volumeserialnumber"].ToString();
if(txt.Length > 0)
Volumeserialnumber = long.Parse(txt,
System.Globalization.NumberStyles.HexNumber);
txt = mo["Size"].ToString();
if(txt.Length > 0)
Size = long.Parse(txt);
Description = mo["Description"].ToString();
}
catch
{
}
finally
{
Shared = shared;
}
}
Using the code
Using the previous collection class should be no surprise: we load it and then we populate the list control with data making use of its IEnumerator
implementation.
if(DiskColl == null)
DiskColl = new DiskCollection();
if(!DiskColl.Load())
{
MessageBox.Show(this,"Unable to retrieve disk info!");
return;
}
DiskList.Items.Clear();
int i = 0;
foreach(DiskCollection.LogicalDriveInfo diskinfo in DiskColl)
{
DiskList.Items.Add(diskinfo.Name.ToString(),i);
DiskList.Items[i].SubItems.Add(diskinfo.Volumeserialnumber.ToString("x"));
DiskList.Items[i].SubItems.Add(diskinfo.Size.ToString("d"));
DiskList.Items[i].SubItems.Add(diskinfo.Shared.ToString());
DiskList.Items[i].SubItems.Add(diskinfo.Description);
i++;
}
History
Decebal Mihailescu is a software engineer with interest in .Net, C# and C++.