Here are some tips on obtaining information about your computer’s physical memory as well as hard drive information.
Drive Information
To obtain information about the various drives in your computer you can use the DriveInfo class. This class contains all sorts of information regarding the drive it references. For this example I will just show you how to obtain the total and free space in Gigabytes for the drive. In this example I will be retrieving info about the C: drive. Also, don’t forget that the sizes returned are in bytes and you should convert them to more meaningful types. Quick info about byte conversion:
Divide by:
2^10 for KB
2^20 for MB
2^30 for GB
2^40 for TB
DriveInfo info = new DriveInfo(“C:\\”);
int freeSpace = (int)(info.AvailableFreeSpace / Math.Pow(2, 30));
int totalSpace = (int)(info.TotalSize / Math.Pow(2, 30));
Physical Memory
To obtain information about your computer’s physical memory you have two options. You can use P/Invoke, which offers much better performance, or WMI for .NET. I will show you using P/Invoke because it’s faster and because I grew up with Win32 and C++ and have sentimental attachment to it. There is a little bit of funkiness to obtaining information about your physical memory in that there are multiple ways to obtain the available memory but only two ways to obtain the total memory (which are p/invoke and WMI). If all you need to know is the amount of available physical memory you can use the PerformanceCounter class which doesn’t require p/invoke but does come with a serious performance hit. Example:
var memCounter = new PerformanceCounter("Memory", "Available MBytes");
var available = Math.Round(memCounter.NextValue() / Math.Pow(2, 10), 2); // Because our performance counter returns the available memory in MB we only need to divide by one magnitude to get to GB
If you want to know both available and physical then you would use p/invoke and Win32 as so:
// Win32 P/Invoke imports
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private class MEMORYSTATUSEX
{
public uint dwLength;
public uint dwMemoryLoad;
public ulong ulTotalPhys;
public ulong ulAvailPhys;
public ulong ulTotalPageFile;
public ulong ulAvailPageFile;
public ulong ulTotalVirtual;
public ulong ulAvailVirtual;
public ulong ulAvailExtendedVirtual;
public MEMORYSTATUSEX()
{
this.dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX));
}
}
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool GlobalMemoryStatusEx([In, Out] MEMORYSTATUSEX lpBuffer);
public static double GetAvailablePhysicalMemory()
{
ulong availableMemory = 0;
MEMORYSTATUSEX memStatus = new MEMORYSTATUSEX();
if (GlobalMemoryStatusEx(memStatus))
{
availableMemory = memStatus.ulAvailPhys;
}
return availableMemory;
}
public static double GetTotalPhysicalMemory()
{
ulong installedMemory = 0;
MEMORYSTATUSEX memStatus = new MEMORYSTATUSEX();
if (GlobalMemoryStatusEx(memStatus))
{
installedMemory = memStatus.ulTotalPhys;
}
return installedMemory;
}
Then use those methods as so:
var Available = Math.Round(Win32Helper.GetAvailablePhysicalMemory() / Math.Pow(2, 30), 2); // I like my available to be semi-accurate so I only round to two decimals
var Total = Math.Round(Win32Helper.GetTotalPhysicalMemory() / Math.Pow(2, 30), 0, MidpointRounding.AwayFromZero); // I like my total to be a nice round number so I round up and chop the decimals
That’s it. Pretty simple.