Click here to Skip to main content
15,897,187 members
Articles / Mobile Apps / Windows Mobile

Display device memory information using P/Invoke

Rate me:
Please Sign up or sign in to vote.
1.36/5 (4 votes)
7 Feb 2008CPOL1 min read 27.1K   190   18  
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.

C#
[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:

C#
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:

C#
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:

C#
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Team Leader
Singapore Singapore
- B.Sc. degree in Computer Science.
- 4+ years experience in Visual C#.net and VB.net
- Obsessed in OOP style design and programming.
- Designing and developing Network security tools.
- Designing and developing a client/server application for sharing files among users in a way other than FTP protocol.
- Designing and implementing GSM gateway applications and bulk messaging.
- Windows Mobile and Symbian Programming
- Having knowledge with ERP solutions

The summary of my skills:
C#, VB.Net#,ASP.net, VC++, Java, WPF,WCF, Oracle, SQL Server, MS Access, Windows NT administration

Cheers
RRave
MCPD,MCTS
http://codegain.com

Comments and Discussions

 
-- There are no messages in this forum --