[DllImport("kernel32.dll")]
static extern void GetSystemInfo(out SYSTEM_INFO lpSystemInfo);
Private Declare Sub GetSystemInfo Lib "kernel32" (<MarshalAs(UnmanagedType.Struct)> ByRef lpSystemInfo As SYSTEM_INFO)
This API mapping demonstrates mapping a union in C#.
The lpMinimumApplicationAddress, lpMaximumApplicationAddress, dwActiveProcessorMask are pointers in kernal32.dll, so the size changes when used from within a 64-bit application. If you need to use these, you will have to cast them to either an uint or a ulong.
using System;
using System.Runtime.InteropServices;
namespace TestGetSystemInfo
{
public class WinApi
{
[DllImport("kernel32.dll")]
public static extern void GetSystemInfo([MarshalAs(UnmanagedType.Struct)] ref SYSTEM_INFO lpSystemInfo);
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEM_INFO
{
internal _PROCESSOR_INFO_UNION uProcessorInfo;
public uint dwPageSize;
public IntPtr lpMinimumApplicationAddress;
public IntPtr lpMaximumApplicationAddress;
public IntPtr dwActiveProcessorMask;
public uint dwNumberOfProcessors;
public uint dwProcessorType;
public uint dwAllocationGranularity;
public ushort dwProcessorLevel;
public ushort dwProcessorRevision;
}
[StructLayout(LayoutKind.Explicit)]
public struct _PROCESSOR_INFO_UNION
{
[FieldOffset(0)]
internal uint dwOemId;
[FieldOffset(0)]
internal ushort wProcessorArchitecture;
[FieldOffset(2)]
internal ushort wReserved;
}
}
public class Program
{
public static void Main(string[] args)
{
WinApi.SYSTEM_INFO sysinfo = new WinApi.SYSTEM_INFO();
WinApi.GetSystemInfo(ref sysinfo);
Console.WriteLine("dwProcessorType ={0}", sysinfo.dwProcessorType.ToString());
Console.WriteLine("dwPageSize ={0}", sysinfo.dwPageSize.ToString());
}
}
}
public enum eOperatingSystem
{
X64,
x86,
Itanium,
Unknown
}
public eOperatingSystem DeterminateOperatingSystemFlavor()
{
// http://msdn2.microsoft.com/en-us/library/ms724958.aspx
eOperatingSystem result = eOperatingSystem.Unknown;
try
{
SYSTEM_INFO l_System_Info = new SYSTEM_INFO();
GetSystemInfo(ref l_System_Info);
switch (l_System_Info.uProcessorInfo.wProcessorArchitecture)
{
case 9: // PROCESSOR_ARCHITECTURE_AMD64
result = eOperatingSystem.X64;
break;
case 6: // PROCESSOR_ARCHITECTURE_IA64
result = eOperatingSystem.Itanium;
break;
case 0: // PROCESSOR_ARCHITECTURE_INTEL
result = eOperatingSystem.x86;
break;
default: // PROCESSOR_ARCHITECTURE_UNKNOWN
result = eOperatingSystem.Unknown;
break;
}
}
catch
{
// Ignore
}
return result;
}
// Remark: This is not just for compile time, but as well as runtime. If you have a 64bit OS, and this was compiled on 32Bit, it will return .X64
public eOperatingSystem DeterminateCompileFlavor()
{
if (System.IntPtr.Size == 8)
return eOperatingSystem.X64;
else
return eOperatingSystem.x86;
}
// NOTE: The above code snippet DOES NOT WORK when running with the 32-bit CLR on a 64-bit machine;
// it will ALWAYS report .Size == 4 because the 32-bit CLR is working in 32-bit mode on the
// 64-bit machine, and is designed to emulate a 32-bit processor in all respects.
//
// Therefore, the GetSytemInfo method should not be used directly. Rather, you should always use
// GetNativeSystemInfo instead, which does work properly. Note also that the operating system
// can be identified by System.Environment.OSVersion.Version.Revision. That should == 64k if
// the OS is 64k [Needs to be fully tested on various machines - ejr].
Do you know one? Please contribute it!