调用WMI
可以用 Win32_Processor 类里面的 AddressWidth 属性来表示系统的位宽,但 AddressWidth 的值受 CPU 和操作系统的双重影响。
具体的值如下面的表格所示:
32bit OS | 64bit OS | |
32bit CPU | AddressWidth = 32 | N/A |
64bit CPU | AddressWidth = 32 | AddressWidth = 64 |
用下面的代码得到AddressWidth的值(注意需添加引用System.Management)
1 public string Detect3264()
2 {
3 ManagementScope Ms = new ManagementScope("\\localhost", new ConnectionOptions());
4 ObjectQuery Query = new ObjectQuery("select AddressWidth from Win32_Processor");
5 ManagementObjectSearcher Searcher = new ManagementObjectSearcher(Ms, Query);
6 ManagementObjectCollection ReturnCollection = Searcher.Get();
7 string addressWidth = null;
8 foreach (ManagementObject Return in ReturnCollection)
9 {
10 addressWidth = Return["AddressWidth"].ToString();
11 }
12 return addressWidth;
13 }
调用Environment
1 bool Is64Bit = Environment.Is64BitOperatingSystem;
为 true 则表示是 64 位,如返回值为 false 则表示为 32 位。
利用IntPtr结构获取系统位宽
这个方法也是最直接的方法,但是有条件限制,利用 IntPtr 结构的 size 属性来查看系统的位宽,程序需要采用 any CPU 的方式进行编辑。正常情况下 int 的位宽是 4 位,即是 32 位操作系统。
1 switch (IntPtr.Size)
2 {
3 case 4:break; //32Bit
4 case 8:break; //64Bit
5 default:break; //Other
6 }
或者
1 switch (Marshal.SizeOf(IntPtr.Zero))
2 {
3 case 4:break; //32Bit
4 case 8:break; //64Bit
5 default:break; //Other
6 }
使用API
64 位 Wnidows 里面有个叫 Wow64 的模拟器技术,可以使 32 位的程序在 64 位 Windows 上运行。 当你想在程序里面针对 32 位/ 64 位系统执行不同代码的时候, 需要判断操作系统是 32 位还是 64 位。 使用 Windows API 函数 GetNativeSystemInfo 可以获得这个信息。(PS:GetNativeSystemInfo 函数从 Windows XP 开始才有, 而 IsWow64Process 函数从 Windows XP with SP2 以及 Windows Server 2003 with SP1 开始才有。 )
所以为了程序不出错,最好用 GetSystemInfo 或者两个 API 看情况调用(代码使用两个 API,分类使用)
1 public enum Platform
2 {
3 X86,
4 X64,
5 IA64,
6 Unknown
7 }
8
9 const ushort PROCESSOR_ARCHITECTURE_INTEL = 0;
10 const ushort PROCESSOR_ARCHITECTURE_IA64 = 6;
11 const ushort PROCESSOR_ARCHITECTURE_AMD64 = 9;
12 const ushort PROCESSOR_ARCHITECTURE_UNKNOWN = 0xFFFF;
13
14 [StructLayout(LayoutKind.Sequential)]
15 internal struct SYSTEM_INFO
16 {
17 public ushort wProcessorArchitecture;
18 public ushort wReserved;
19 public uint dwPageSize;
20 public IntPtr lpMinimumApplicationAddress;
21 public IntPtr lpMaximumApplicationAddress;
22 public UIntPtr dwActiveProcessorMask;
23 public uint dwNumberOfProcessors;
24 public uint dwProcessorType;
25 public uint dwAllocationGranularity;
26 public ushort wProcessorLevel;
27 public ushort wProcessorRevision;
28 };
29
30 [DllImport("kernel32.dll")]
31 static extern void GetNativeSystemInfo(ref SYSTEM_INFO lpSystemInfo);
32
33 [DllImport("kernel32.dll")]
34 static extern void GetSystemInfo(ref SYSTEM_INFO lpSystemInfo);
35
36 public Platform GetPlatform()
37 {
38 SYSTEM_INFO sysInfo = new SYSTEM_INFO();
39
40 if(System.Environment.OSVersion.Version.Major > 5 ||
41 (System.Environment.OSVersion.Version.Major == 5 && System.Environment.OSVersion.Version.Minor >= 1))
42 {
43 GetNativeSystemInfo(ref sysInfo);
44 }
45 else
46 {
47 GetSystemInfo(ref sysInfo);
48 }
49
50 switch(sysInfo.wProcessorArchitecture)
51 {
52 case PROCESSOR_ARCHITECTURE_IA64:
53 return Platform.IA64;
54
55 case PROCESSOR_ARCHITECTURE_AMD64:
56 return Platform.X64;
57
58 case PROCESSOR_ARCHITECTURE_INTEL:
59 return Platform.X86;
60
61 default:
62 return Platform.Unknown;
63 }
64 }
Windows API 还提供了 IsWow64Process 函数判断程序是不是运行在 Wow64 模拟器之上。
1 [DllImport("kernel32.dll")]
2 static extern IntPtr GetCurrentProcess();
3
4 [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
5 [return: MarshalAs(UnmanagedType.Bool)]
6 static extern bool IsWow64Process(
7 [In] IntPtr processHandle,
8 [Out, MarshalAs(UnmanagedType.Bool)] out bool wow64Process);
9
10 bool isWow64 = false;
11 if ((System.Environment.OSVersion.Version.Major == 5 && System.Environment.OSVersion.Version.Minor >= 1) ||
12 System.Environment.OSVersion.Version.Major > 5)
13 {
14 SafeProcessHandle processHandle = GetProcessHandle((uint)System.Diagnostics.Process.GetCurrentProcess().Id);
15 //或者 SafeProcessHandle processHandle = GetProcessHandle(GetCurrentProcess());
16 if (!NativeMethods.IsWow64Process(processHandle, out isWow64))
17 {
18 throw new Win32Exception(Marshal.GetLastWin32Error());
19 }
20 }
还有 GetProcAddress ,在这里就不赘述了。