有如下的程序段(GetTotalMem.cs):
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace fdx
{
public struct MemoryStatus
{
public uint Length;
public uint MemoryLoad;
public uint TotalPhysical;
public uint AvailablePhysical;
public uint TotalPageFile;
public uint AvailablePageFile;
public uint TotalVirtual;
public uint AvailableVirtual;
}
public class Program
{
[DllImport( " kernel32.dll ")]
public static extern void GlobalMemoryStatus( out MemoryStatus stat);
public static void Main()
{
MemoryStatus stat = new MemoryStatus();
GlobalMemoryStatus( out stat);
uint ram = stat.TotalPhysical;
Console.WriteLine(ram);
Console.ReadKey();
}
}
}
using System.IO;
using System.Runtime.InteropServices;
namespace fdx
{
public struct MemoryStatus
{
public uint Length;
public uint MemoryLoad;
public uint TotalPhysical;
public uint AvailablePhysical;
public uint TotalPageFile;
public uint AvailablePageFile;
public uint TotalVirtual;
public uint AvailableVirtual;
}
public class Program
{
[DllImport( " kernel32.dll ")]
public static extern void GlobalMemoryStatus( out MemoryStatus stat);
public static void Main()
{
MemoryStatus stat = new MemoryStatus();
GlobalMemoryStatus( out stat);
uint ram = stat.TotalPhysical;
Console.WriteLine(ram);
Console.ReadKey();
}
}
}
在64位机器上用命令
csc GetTotalMem.cs
编译后的程序运行在输入key时总会出错,说程序停止工作。
而用在命令行先后加上/debug标识,则又一切OK。
现在转回去,指定编译平台为
csc GetTotalMem.cs /platform:x86
则运行正常。
指定编译平台为
csc GetTotalMem.cs /platform:x64
继续出错。然后再加上/debug标识,又正常。
Visual Studio 下的项目倒是一切正常,不知道是什么地方又藏着一个问题,先写到这里,看看以后有没有更新的发现。
---------------------------------------------------华丽的日期分隔线-----------------------------------------------------------
昨天的代码经过研究,发现问题出在C#调用C++的库的时候的引用方式以及结构定义的数据不能容纳C++库函数返回的数据上。
新的代码:
View Code
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace fdx
{
[StructLayout(LayoutKind.Sequential)]
public struct MEMORYSTATUSEX
{
public uint dwLength;
public uint dwMemoryLoad;
public ulong ullTotalPhys;
public ulong ullAvailPhys;
public ulong ullTotalPageFile;
public ulong ullAvailPageFile;
public ulong ullTotalVirtual;
public ulong ullAvailVirtual;
public ulong ullAvailExtendedVirtual;
}
[StructLayout(LayoutKind.Sequential)]
public struct MemoryStatus
{
public uint Length;
public uint MemoryLoad;
public ulong TotalPhysical;
public ulong AvailablePhysical;
public ulong TotalPageFile;
public ulong AvailablePageFile;
public ulong TotalVirtual;
public ulong AvailableVirtual;
}
public class Program
{
[DllImport( " kernel32.dll ")]
public static extern void GlobalMemoryStatusEx( ref MEMORYSTATUSEX stat);
[DllImport( " kernel32.dll ")]
public static extern void GlobalMemoryStatus( ref MemoryStatus stat);
public static void Main()
{
MEMORYSTATUSEX stat = new MEMORYSTATUSEX();
stat.dwLength = ( uint)Marshal.SizeOf( typeof(MEMORYSTATUSEX));
GlobalMemoryStatusEx( ref stat);
long ram = ( long)stat.ullAvailPhys/ 1024/ 1024;
Console.WriteLine(stat.ullAvailPhys/ 1024/ 1024);
Console.WriteLine(stat.ullTotalPhys / 1024 / 1024);
Console.WriteLine(stat.ullTotalVirtual / 1024 / 1024/ 1024);
// Console.ReadKey();
MemoryStatus stat2 = new MemoryStatus();
stat2.Length=( uint)Marshal.SizeOf( typeof(MemoryStatus));
GlobalMemoryStatus( ref stat2);
Console.WriteLine(stat2.AvailablePhysical/ 1024/ 1024);
}
}
}
using System.IO;
using System.Runtime.InteropServices;
namespace fdx
{
[StructLayout(LayoutKind.Sequential)]
public struct MEMORYSTATUSEX
{
public uint dwLength;
public uint dwMemoryLoad;
public ulong ullTotalPhys;
public ulong ullAvailPhys;
public ulong ullTotalPageFile;
public ulong ullAvailPageFile;
public ulong ullTotalVirtual;
public ulong ullAvailVirtual;
public ulong ullAvailExtendedVirtual;
}
[StructLayout(LayoutKind.Sequential)]
public struct MemoryStatus
{
public uint Length;
public uint MemoryLoad;
public ulong TotalPhysical;
public ulong AvailablePhysical;
public ulong TotalPageFile;
public ulong AvailablePageFile;
public ulong TotalVirtual;
public ulong AvailableVirtual;
}
public class Program
{
[DllImport( " kernel32.dll ")]
public static extern void GlobalMemoryStatusEx( ref MEMORYSTATUSEX stat);
[DllImport( " kernel32.dll ")]
public static extern void GlobalMemoryStatus( ref MemoryStatus stat);
public static void Main()
{
MEMORYSTATUSEX stat = new MEMORYSTATUSEX();
stat.dwLength = ( uint)Marshal.SizeOf( typeof(MEMORYSTATUSEX));
GlobalMemoryStatusEx( ref stat);
long ram = ( long)stat.ullAvailPhys/ 1024/ 1024;
Console.WriteLine(stat.ullAvailPhys/ 1024/ 1024);
Console.WriteLine(stat.ullTotalPhys / 1024 / 1024);
Console.WriteLine(stat.ullTotalVirtual / 1024 / 1024/ 1024);
// Console.ReadKey();
MemoryStatus stat2 = new MemoryStatus();
stat2.Length=( uint)Marshal.SizeOf( typeof(MemoryStatus));
GlobalMemoryStatus( ref stat2);
Console.WriteLine(stat2.AvailablePhysical/ 1024/ 1024);
}
}
}
现在问题解决。debug方式会为我们屏蔽掉很多越界异常,所以在VS2010下虽然结果不对,但是还是正确退出。
顺便提供另外一个获取内存信息的方法( WMI)
代码:
View Code
///
<summary>
/// 内存类
/// </summary>
public class Memory
{
private string _totalMem;
private string _availMem;
private string _usageRate;
/// <summary>
/// 内存使用率
/// </summary>
public string UsageRate
{
get { return _usageRate; }
set { _usageRate = value; }
}
/// <summary>
/// 总可用内存的大小
/// </summary>
public string AvailMem
{
get { return _availMem; }
set { _availMem = value; }
}
/// <summary>
/// 总物理内存的大小
/// </summary>
public string TotalMem
{
get { return _totalMem; }
set { _totalMem = value; }
}
}
public static bool ReadMemory(Memory memory)
{
try
{
#region 内存使用情况
double totalMem = 0.0;
double AvailMem = 0.0;
// 计算物理内存
ManagementObjectSearcher search = new ManagementObjectSearcher( " Select * from Win32_PhysicalMemory ");
int i = 0;
ManagementObjectCollection infos = search.Get();
foreach (ManagementObject info in infos)
{
i = i + 1;
totalMem += Convert.ToDouble(info[ " Capacity "].ToString()) / 1024/ 1024;
}
memory.TotalMem = totalMem.ToString();
// 计算剩余内存
search = new ManagementObjectSearcher( " Select AvailableMBytes from Win32_PerfRawData_PerfOS_Memory ");
i = 0;
foreach (ManagementObject info in search.Get())
{
i = i + 1;
AvailMem += Convert.ToDouble(info[ " AvailableMBytes "].ToString());
}
memory.AvailMem = AvailMem.ToString();
memory.UsageRate = string.Format( " {0} ", Convert.ToDouble(( 1 - AvailMem / totalMem) * 100));
#endregion
return true;
}
catch(Exception e)
{
Console.WriteLine(e.Message);
return false;
}
}
/// 内存类
/// </summary>
public class Memory
{
private string _totalMem;
private string _availMem;
private string _usageRate;
/// <summary>
/// 内存使用率
/// </summary>
public string UsageRate
{
get { return _usageRate; }
set { _usageRate = value; }
}
/// <summary>
/// 总可用内存的大小
/// </summary>
public string AvailMem
{
get { return _availMem; }
set { _availMem = value; }
}
/// <summary>
/// 总物理内存的大小
/// </summary>
public string TotalMem
{
get { return _totalMem; }
set { _totalMem = value; }
}
}
public static bool ReadMemory(Memory memory)
{
try
{
#region 内存使用情况
double totalMem = 0.0;
double AvailMem = 0.0;
// 计算物理内存
ManagementObjectSearcher search = new ManagementObjectSearcher( " Select * from Win32_PhysicalMemory ");
int i = 0;
ManagementObjectCollection infos = search.Get();
foreach (ManagementObject info in infos)
{
i = i + 1;
totalMem += Convert.ToDouble(info[ " Capacity "].ToString()) / 1024/ 1024;
}
memory.TotalMem = totalMem.ToString();
// 计算剩余内存
search = new ManagementObjectSearcher( " Select AvailableMBytes from Win32_PerfRawData_PerfOS_Memory ");
i = 0;
foreach (ManagementObject info in search.Get())
{
i = i + 1;
AvailMem += Convert.ToDouble(info[ " AvailableMBytes "].ToString());
}
memory.AvailMem = AvailMem.ToString();
memory.UsageRate = string.Format( " {0} ", Convert.ToDouble(( 1 - AvailMem / totalMem) * 100));
#endregion
return true;
}
catch(Exception e)
{
Console.WriteLine(e.Message);
return false;
}
}