65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 P/Invoke 显示设备内存信息

starIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIconemptyStarIcon

1.36/5 (4投票s)

2008年2月8日

CPOL

1分钟阅读

viewsIcon

27625

downloadIcon

203

使用 P/Invoke 和 Compact Framework 获取内存状态和存储卡信息。

DeviceMemoryInfo/devicememorystate.jpg

引言

过去几周,我在 MSDN 论坛和 CodeProject 论坛上看到一些人询问如何获取内存状态、存储卡容量等。本文提供了一个静态类,您可以非常容易地将其直接用于您的项目中。

背景

在该类中,有五个属性:

  • HasStorageCardPresent - 指示是否已安装存储卡。
  • FreeBytesAvailable - 提供设备目录中可用空闲字节数。
  • TotalBytes – 提供设备内存中的总字节数。
  • TotalFreeBytes – 提供设备内存中的总空闲空间。
  • DirectoryName - 指定您希望获取哪个目录的容量;如果未设置此项,则 Windows 目录为默认目录。

使用代码

类名为 DeviceMemoryInfo。基本上,该类表示上述属性。这些值是通过类中使用的 P/Invoke 方法获取的。

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

上述方法在 Compact Framework 中不可直接使用,因此我们使用 P/Invoke 技术并调用我们的管理器代码。请参阅下面的代码

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;
    }
}

在此方法中,我使用一个结构体 (DiskFreeSpace) 来传递给 P/Invoke 方法。

这是该结构体:

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; 
}

MSDN 中提供了设备 API 所有原生结构体的清晰解释。

这是 DeviceMemoryInfo 类的完整实现:

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; 
        } 
    } 
}

缺点

我希望上述类能够解决很多疑问。如果您发现此处有任何错误,请在下面的论坛中指出。

历史

  • 第一个版本 - 2008 年 08 月 02 日。
© . All rights reserved.