Introduction
This article shows how to get system drives information using
System.Management
namespace and use Sysetm.IO
namespace to get directories and files information to populate
TreeView
and
ListView
controls.
Getting Started
First we need to gather information on all the drives my computer have access to,
and display the name and type of drive in the TreeView
control. We can
query the System.Management
namespace to access drive information using the
ManagementObjectSearcher
class. It accepts a SQL like query as a
parameter and returns a ManagementOjbectCollection
class containing the
drive information we requested. We now have all the drives information at our
disposal (such as drive name, type, volume, description, etc...).
private void PopulateDriveList()
{
TreeNode nodeTreeNode;
int imageIndex = 0;
int selectIndex = 0;
const int Removable = 2;
const int LocalDisk = 3;
const int Network = 4;
const int CD = 5;
this.Cursor = Cursors.WaitCursor;
tvFolders.Nodes.Clear();
nodeTreeNode = new TreeNode("My Computer",0,0);
tvFolders.Nodes.Add(nodeTreeNode);
TreeNodeCollection nodeCollection = nodeTreeNode.Nodes;
ManagementObjectCollection queryCollection = getDrives();
foreach ( ManagementObject mo in queryCollection)
{
switch (int.Parse( mo["DriveType"].ToString()))
{
case Removable:
imageIndex = 5;
selectIndex = 5;
break;
case LocalDisk:
imageIndex = 6;
selectIndex = 6;
break;
case CD:
imageIndex = 7;
selectIndex = 7;
break;
case Network:
imageIndex = 8;
selectIndex = 8;
break;
default:
imageIndex = 2;
selectIndex = 3;
break;
}
nodeTreeNode = new TreeNode(mo["Name"].ToString()
+ "\\" ,imageIndex,selectIndex);
//add new node
nodeCollection.Add(nodeTreeNode);
}
//Init files ListView
InitListView();
this.Cursor = Cursors.Default;
}
protected ManagementObjectCollection getDrives()
{
//get drive collection
ManagementObjectSearcher query = new
ManagementObjectSearcher("SELECT * From Win32_LogicalDisk ");
ManagementObjectCollection queryCollection = query.Get();
return queryCollection;
}
Directories and Files
When we click on a drive or a directory in the TreeView
, we need to
check if the drive or directory exists, before proceeding any further. Now we can get
the directories for the current selection in the TreeView
by using the
Directory
class from the System.IO
namespace.
Calling the Directory.GetDirectories
method with the current
node path as the parameter, will return an array of directories. We can loop through
the directories array to populate sub-nodes under the current selected node. To get the
currently selected node's files, we need to call the Directory.GetFiles
method with the current node path as the parameter. This will return an array of
files for the selected drive or directory. Now we can populate the
ListView
with the file array by looping through each array
element and call FileInfo
class to get the file size,
creation date, and modified date.
protected void PopulateDirectory(TreeNode nodeCurrent,
TreeNodeCollection nodeCurrentCollection)
{
TreeNode nodeDir;
int imageIndex = 2;
int selectIndex = 3;
if (nodeCurrent.SelectedImageIndex != 0)
{
try
{
if(Directory.Exists(getFullPath(nodeCurrent.FullPath))
== false)
{
MessageBox.Show("Directory or path " +
nodeCurrent.ToString() + " does not exist.");
}
else
{
PopulateFiles(nodeCurrent);
string[] stringDirectories =
Directory.GetDirectories(getFullPath
(nodeCurrent.FullPath));
string stringFullPath = "";
string stringPathName = "";
foreach (string stringDir in stringDirectories)
{
stringFullPath = stringDir;
stringPathName = GetPathName(stringFullPath);
nodeDir = new TreeNode(stringPathName.ToString(),
imageIndex,selectIndex);
nodeCurrentCollection.Add(nodeDir);
}
}
}
catch (IOException e)
{
MessageBox.Show("Error:
Drive not ready or directory does not exist.");
}
catch (UnauthorizedAccessException e)
{
MessageBox.Show("Error:
Drive or directory access denided.");
}
catch (Exception e)
{
MessageBox.Show("Error: " + e);
}
}
}
protected string GetPathName(string stringPath)
{
string[] stringSplit = stringPath.Split('\\');
int _maxIndex = stringSplit.Length;
return stringSplit[_maxIndex-1];
}
protected void PopulateFiles(TreeNode nodeCurrent)
{
string[] lvData = new string[4];
InitListView();
if (nodeCurrent.SelectedImageIndex != 0)
{
if(Directory.Exists((string)
getFullPath(nodeCurrent.FullPath)) == false)
{
MessageBox.Show("Directory or path " +
nodeCurrent.ToString() + " does not exist.");
}
else
{
try
{
string[] stringFiles = Directory.GetFiles
(getFullPath(nodeCurrent.FullPath));
string stringFileName = "";
DateTime dtCreateDate, dtModifyDate;
Int64 lFileSize = 0;
foreach (string stringFile in stringFiles)
{
stringFileName = stringFile;
FileInfo objFileSize = new
FileInfo(stringFileName);
lFileSize = objFileSize.Length;
dtCreateDate = objFileSize.CreationTime;
dtModifyDate = objFileSize.LastWriteTime;
lvData[0] = GetPathName(stringFileName);
lvData[1] = formatSize(lFileSize);
if (TimeZone.CurrentTimeZone.
IsDaylightSavingTime(dtCreateDate) == false)
{
lvData[2] = formatDate(dtCreateDate.AddHours(1));
}
else
{
lvData[2] = formatDate(dtCreateDate);
}
if (TimeZone.CurrentTimeZone.
IsDaylightSavingTime(dtModifyDate) == false)
{
lvData[3] = formatDate(dtModifyDate.AddHours(1));
}
else{
lvData[3] = formatDate(dtModifyDate);
}
ListViewItem lvItem = new ListViewItem(lvData,0);
lvFiles.Items.Add(lvItem);
}
}
catch (IOException e)
{
MessageBox.Show("Error:
Drive not ready or directory does not exist.");
}
catch (UnauthorizedAccessException e)
{
MessageBox.Show("Error:
Drive or directory access denided.");
}
catch (Exception e)
{
MessageBox.Show("Error: " + e);
}
}
}
}
protected string getFullPath(string stringPath)
{
stringParse = "";
stringParse = stringPath.Replace("My Computer\\", "");
return stringParse;
}
protected string formatDate(DateTime dtDate)
{
//Get date and time in short format
string stringDate = "";
stringDate = dtDate.ToShortDateString().ToString()
+ " " + dtDate.ToShortTimeString().ToString();
return stringDate;
}
protected string formatSize(Int64 lSize)
{
//Format number to KB
string stringSize = "";
NumberFormatInfo myNfi = new NumberFormatInfo();
Int64 lKBSize = 0;
if (lSize < 1024 )
{
if (lSize == 0)
{
//zero byte
stringSize = "0";
}
else
{
//less than 1K but not zero byte
stringSize = "1";
}
}
else
{
//convert to KB
lKBSize = lSize / 1024;
//format number with default format
stringSize = lKBSize.ToString("n",myNfi);
//remove decimal
stringSize = stringSize.Replace(".00", "");
}
return stringSize + " KB";
}
Formating Numbers
Instead of writing string parsing functions to format the file size with comma
in the thousand and millionth position, I use the NumberFormatInfo
class
in System.Globalization
namespace to format the number, when I
convert the number to the string format.
protected string formatSize(Int64 lSize)
{
string stringSize = "";
NumberFormatInfo myNfi = new NumberFormatInfo();
Int64 lKBSize = 0;
if (lSize < 1024 )
{
:
:
}
else
{
lKBSize = lSize / 1024;
stringSize = lKBSize.ToString("n",myNfi);
stringSize = stringSize.Replace(".00", "");
}
return stringSize + " KB";
}
Day Light Saving Time
At first glance, it looks like
FileInfo objFileSize = new FileInfo(stringFileName)
will give you all the correct information about the file to display on the screen.
But it turns out that the file date time may not be correct due to Day Light Saving Time
settings on your machine and how the file was saved. The files that does not have
the Day Light Saving Time set to true will have the create, modify, and access time
off by one hour. We need to check for this condition using the function
TimeZone.CurrentTimeZone.IsDaylightSavingTime(dtCreateDate)
.
This function returns a Boolean
, true
if the file
Day Light Saving Time was set and returns a false
if it was not set.
Then we can adjust the time for those files that does not have the Day Light Saving
Time setting set, by adding one hour to the file time.
protected void PopulateFiles(TreeNode nodeCurrent)
{
string[] lvData = new string[4];
InitListView();
if (nodeCurrent.SelectedImageIndex != 0)
{
if(Directory.Exists((string)
getFullPath(nodeCurrent.FullPath)) == false)
{
MessageBox.Show("Directory or path " +
nodeCurrent.ToString() + " does not exist.");
}
else
{
try
{
string[] stringFiles = Directory.
GetFiles(getFullPath(nodeCurrent.FullPath));
string stringFileName = "";
DateTime dtCreateDate, dtModifyDate;
Int64 lFileSize = 0;
foreach (string stringFile in stringFiles)
{
stringFileName = stringFile;
FileInfo objFileSize = new FileInfo(stringFileName);
lFileSize = objFileSize.Length;
dtCreateDate = objFileSize.CreationTime;
dtModifyDate = objFileSize.LastWriteTime;
lvData[0] = GetPathName(stringFileName);
lvData[1] = formatSize(lFileSize);
if (TimeZone.CurrentTimeZone.
IsDaylightSavingTime(dtCreateDate) == false)
{
lvData[2] = formatDate(dtCreateDate.AddHours(1));
}
else
{
lvData[2] = formatDate(dtCreateDate);
}
if (TimeZone.CurrentTimeZone.
IsDaylightSavingTime(dtModifyDate) == false)
{
lvData[3] = formatDate(dtModifyDate.AddHours(1));
}
else {
lvData[3] = formatDate(dtModifyDate);
}
ListViewItem lvItem = new ListViewItem(lvData,0);
lvFiles.Items.Add(lvItem);
}
}
catch (IOException e)
{
MessageBox.Show("Error:
Drive not ready or directory does not exist.");
}
catch (UnauthorizedAccessException e)
{
MessageBox.Show("Error:
Drive or directory access denied.");
}
catch (Exception e)
{
MessageBox.Show("Error: " + e);
}
}
}
}
Conclusion
We have used the System.Management
namespace to get information on
all the available drives in the system and used the Directory
and
FileInfo
classes in the System.IO
namespace to get information about directories and files. There are many other
features available in the Directory
and File
classes we did not touch upon, like the ones for creating directory, deleting directory,
creating file, copy file, move file, etc. Also with System.Management
namespace, you could get access to management information about the system,
devices, and application in the Windows Management Instrumentation (WMI) infrastructure.
We can query for information such as how much space is left on the drive, what is the current
CPU utilization and much more, using the classes in the
System.Management
namespace.
You could find out more about these namespaces at http://msdn.microsoft.com.