This tutorial shows you how to get a list of the volumes (drives) on the current system, using .NET 2.0. It also shows you how to make use of a 3D Pie Chart library and of the FillPie() method.
The tutorial can prove useful to beginner C# programmers who want to get a more hands-on approach, programmers who want to accommodate the new .NET 2.0 framework or simply programmers who want to see how to list the computer’s hard drives, cd roms and other volumes, and programmers who want to see a sample approach to using the 3D Pie Chart library. Also, it’s about time I mention that 3D Pie Chart is the wonderful work of Julijan Sribar and was posted at CodeProject.
Here is how the window of our application, which we call DriveStat and which you can download here, looks like in Windows Vista Beta 1:
The application will work on any Windows operating system that has .NET Framework 2.0 installed.
Since this project is fairly big to be discussed in a single tutorial, we will cover only the interesting parts. First download the project and check out the source code, which is commented.
Enumerating the drives
The most important part of our application is getting a list of drives such as the one that show up in Computer (or My Computer in older Windows versions). We do that in the form’s Load event:
private void frmMain_Load(object sender, EventArgs e)
{
stsAppInfo.Text = "Loading drive list";
try
{
DriveInfo[] driveList = DriveInfo.GetDrives();
foreach (DriveInfo drive in driveList)
{
// Check if the drive is ready to avoid exceptions
if (!drive.IsReady)
continue;
string driveDisplayName = $"{drive.Name} ({drive.VolumeLabel})";
int imageIndex = GetImageIndexForDriveType(drive.DriveType);
treeDrives.Nodes.Add(drive.Name, driveDisplayName, imageIndex);
}
stsAppInfo.Text = "Done";
}
catch (Exception ex)
{
stsAppInfo.Text = "Error loading drives";
// Handle the exception or log it
}
}
private int GetImageIndexForDriveType(DriveType driveType)
{
switch (driveType)
{
case DriveType.Fixed:
return 3;
case DriveType.CDRom:
return 0;
case DriveType.Removable:
return 2;
case DriveType.Network:
return 4;
case DriveType.Ram:
return 6;
default:
return -1; // Or a default image index
}
}
Here we populate a TreeView with the drives available on the computer. Depending on the type of drive (HDD, floppy, etc.) we set an icon for the TreeView node. The icon we set is taken from an ImageList named imgDriveIcons which was assigned to the TreeView. Also we update the StatusStrip label.
Getting drive information (free space, used space, total size…)
Now each time a node in the TreeView is selected (each node being a drive), we want to retrieve information about that drive. So we handle this in the AfterSelect event of the TreeView:
private void treeDrives_AfterSelect(object sender, TreeViewEventArgs e)
{
   stsAppInfo.Text = "Loading drive information";
   // Get drive information for the currently selected drive
   // To the method we pass the drive path (C:\ for ex.)
   GetDriveInfo(treeDrives.SelectedNode.Name);
   stsAppInfo.Text = "Done";
}
As you can see, a method is called here. This method takes one parameter, the name of the node (thus of the drive) which looks like C:\, D:\, E:\ and so on. So we pass the path of the drive we want to retrieve the details of. The GetDriveInfo() method looks like this:
private void GetDriveInfo(string driveName)
{
   // Get drive information for the passed drive path
   DriveInfo driveInfo;
   driveInfo = new DriveInfo(driveName);
   // Clear any icons that can be in imgDriveIcon
   imgDriveIcon.Images.Clear();
   if (driveInfo.DriveType == DriveType.Fixed)
   {
      // Set imgDriveIcon to hold the icon of the current drive
      imgDriveIcon.Images.Add(this.imgDriveIcons.Images[3]);
      // The TreeView requires a SelectedImage for the selected node
      // we don't need that so we set it back to the icon of the current drive
      treeDrives.SelectedImageIndex = 3;
   }
   else if (driveInfo.DriveType == DriveType.CDRom)
   {
      imgDriveIcon.Images.Add(this.imgDriveIcons.Images[0]);
      treeDrives.SelectedImageIndex = 0;
   }
   else if (driveInfo.DriveType == DriveType.Removable)
   {
      imgDriveIcon.Images.Add(this.imgDriveIcons.Images[2]);
      treeDrives.SelectedImageIndex = 2;
   }
   else if (driveInfo.DriveType == DriveType.Network)
   {
      imgDriveIcon.Images.Add(this.imgDriveIcons.Images[4]);
      treeDrives.SelectedImageIndex = 4;
   }
   else if (driveInfo.DriveType == DriveType.Ram)
   {
      imgDriveIcon.Images.Add(this.imgDriveIcons.Images[6]);
      treeDrives.SelectedImageIndex = 6;
   }
   // Try to get the VolumeLabel and Name
   try
   {
      lnkVolumeName.Text = driveInfo.VolumeLabel + " (" + driveInfo.Name + ")";
   }
   catch
   {
      lnkVolumeName.Text = "Drive is not ready.";
   }
   try
   {
      // Initialize the variables
      FreeSpace = driveInfo.TotalFreeSpace;
      TotalSize = driveInfo.TotalSize;
      UsedSpace = TotalSize - FreeSpace;
      // Calculate the sweep (needed for the small pie)
      Sweep = 360f * FreeSpace / TotalSize;
      // Set the labels
      lblFileSystem.Text = driveInfo.DriveFormat;
      lblFreeSpace.Text = this.ConvertBytesToMB(FreeSpace) + " MB";
      lblUsedSpace.Text = this.ConvertBytesToMB(UsedSpace) + " MB";
      lblTotalSize.Text = this.ConvertBytesToMB(TotalSize) + " MB" ;
   }
   catch
   {
      FreeSpace = 0;
      TotalSize = 0;
      UsedSpace = 0;
      Sweep = 0;
      lblFileSystem.Text = "N/A";
      lblFreeSpace.Text = "N/A";
      lblUsedSpace.Text = "N/A";
      lblTotalSize.Text = "N/A";
   }
   // The rectangle in which the small pie will lie
   SmallRect = new Rectangle(5, 5, 85, 85);
   // The two brushes needed to draw the small pie
   BlueBrush = new LinearGradientBrush(SmallRect, Color.FromArgb(0, 57, 150), Color.FromArgb(21, 115, 255), 45);
   RedBrush = new LinearGradientBrush(SmallRect, Color.FromArgb(255, 5, 5), Color.FromArgb(255, 135, 135), 45);
   // Invalidate these two panels so that their content is refreshed
   pnlTitle.Invalidate();
   pnlSmallPie.Invalidate();
   // Call UpdateChart() to update the big Pie Chart
   UpdateChart();
}
Many things happen here. Information about the volume is retrieved and converted using an useful method called ConvertBytesToMB. Variables are initialized with disk space information. Also, brushes and other elements required for the small pie chart are defined. Hopefully the comments help you figure out the purpose of each piece of code in this method.
Having a second look over this method, I can see it can be optimized, and it certainly will in a future version.
If you have any comments regarding this application and its source code, be my guest.