Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Display device memory information using P/Invoke

0.00/5 (No votes)
7 Feb 2008 1  
P/Invoke with Compact Framework to get the memory status and storage card information.

DeviceMemoryInfo/devicememorystate.jpg

Introduction

I saw in the last few weeks in MSDN forums and CodeProject forums a few guys asking how to get the memory status, storage card capacity, and etc… This article has a static class that you can directly use with your project very easily.

Background

In the class, there are five properties:

  • HasStorageCardPresent - This indicates a storage card is presently installed.
  • FreeBytesAvailable - This gives the long bytes for the free space in the device directory.
  • TotalBytes – This gives the total bytes in the device memory.
  • TotalFreeBytes – This gives the total free space in the device memory.
  • DirectoryName - This specifies which directory capacity you want when you want to set the directory name; if it doesn’t set this, the windows directory is the default.

Using the code

The class name is DeviceMemoryInfo. Basically, this class represents the above properties. These values are take using a P/Invoke method used within the class.

[DllImport("coredll",SetLastError=true)] 
private static extern bool GetDiskFreeSpaceEx(string directoryName, 
        ref long freeBytesAvailable, ref long totalBytes, ref long totalFreeBytes);

The above method is not directly available in the Compact Framework, so we use the P/Invoke technique and call our manager code. See the code below:

private static void GetStoreageSize()
{ 
    DiskFreeSpace result = new DiskFreeSpace(); 
    if(string.IsNullOrEmpty(directoryName))
    {
        directoryName = @"\Windows";
    }
    if(!GetDiskFreeSpaceEx(directoryName, ref result.FreeBytesAvailable,
          ref result.TotalBytes, ref result.TotalFreeBytes))
    {
        throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error(),
                                      "Error retrieving free disk space"); 
    }
    else
    { 
        freeBytesAvailable = result.FreeBytesAvailable;
        totalBytes = result.TotalBytes;
        totalFreeBytes = result.TotalFreeBytes;
    }
}

In this method, I use a struct (DiskFreeSpace) to pass the P/Invoke method.

Here is the struct:

private struct DiskFreeSpace
{ 
    /// <summary>
    /// The total number of free bytes on the disk that are
    /// available to the user associated with the calling thread.
    /// </summary>
    public long FreeBytesAvailable; 
    /// <summary>
    /// The total number of bytes on the disk that are available
    /// to the user associated with the calling thread.
    /// </summary>
    public long TotalBytes; 
    /// <summary>
    /// The total number of free bytes on the disk.
    /// </summary>
    public long TotalFreeBytes; 
}

A clear explanation of all native structs for device APIs is available in MSDN.

Here is the full implementation for the DeviceMemoryInfo class:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.InteropServices; 

namespace GetStorageCard
{ 
    public class DeviceMemoryInfo
    {
        public static bool HasStorageCardPresent
        { 
            get 
            { 
                return DeviceMemoryInfo.IsStorageCard(); 
            }
        }
        private static long freeBytesAvailable = 0; 

        public static long FreeBytesAvailable 
        { 
            get
            { 
                DeviceMemoryInfo.GetStoreageSize();
                return freeBytesAvailable; 
            } 
        }
        private static long totalBytes = 0; 

        public static long TotalBytes
        { 
            get
            {
                DeviceMemoryInfo.GetStoreageSize();
                return totalBytes; 
            } 
        } 
        private static long totalFreeBytes = 0; 

        public static long TotalFreeBytes 
        { 
            get
            {
                DeviceMemoryInfo.GetStoreageSize();
                return totalFreeBytes;
            } 
        } 
        static string directoryName = string.Empty; 
        /// <summary>
        /// Set directory Name before get Memory status, default is windows directory 
        /// </summary> 
        public static string DirectoryName 
        {
            get
            { 
                return directoryName; 
            } 
            set  
            { 
                directoryName = value;
            } 
        } 
        [DllImport("coredll",SetLastError=true)]
        private static extern bool GetDiskFreeSpaceEx(string directoryName, 
                ref long freeBytesAvailable, ref long totalBytes, ref long totalFreeBytes);

        private static void GetStoreageSize()
        { 
            DiskFreeSpace  result = new DiskFreeSpace();
            if(string.IsNullOrEmpty(directoryName))
            { 
                directoryName = @"\Windows";
            } 
            if(!GetDiskFreeSpaceEx(directoryName, ref result.FreeBytesAvailable, 
                     ref result.TotalBytes,ref result.TotalFreeBytes)) 
            { 
                throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error(), 
                          "Error retrieving free disk space"); 
            } 
            else
            {
                freeBytesAvailable = result.FreeBytesAvailable; 
                totalBytes = result.TotalBytes;
                totalFreeBytes = result.TotalFreeBytes;
            }
        }
        private struct DiskFreeSpace
        { 
            /// <summary> 
            /// The total number of free bytes on the disk that are
            /// available to the user associated with the calling thread.
            /// </summary>
            public long FreeBytesAvailable; 
            /// <summary>
            /// The total number of bytes on the disk that are available
            /// to the user associated with the calling thread.
            /// </summary>
            public long TotalBytes;
            /// <summary>
            /// The total number of free bytes on the disk.
            /// </summary>
            public long TotalFreeBytes;
        } 
        private static bool IsStorageCard()
        { 
            bool hasStorageCard = false; 
            DirectoryInfo storeageCard = new DirectoryInfo(@"\"); 
            foreach (DirectoryInfo directory in storeageCard.GetDirectories())
            { 
                if (directory.Attributes == 
                  (FileAttributes.Temporary |FileAttributes.Directory))
                { 
                    hasStorageCard = true; 
                    break; 
                } 
                else 
                {
                    hasStorageCard = false; 
                }
            }
            return hasStorageCard; 
        } 
    } 
}

Cons

I hope the above class will sort out a lot of doubts. If you find anything wrong here, please indicate it in the forum below.

History

  • First version - 08:02:2008.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here