getsysteminfo (kernel32)
Last changed: Milkenm-65.49.2.17

.
Summary

C# Signature:

[DllImport("kernel32.dll")]
static extern void GetSystemInfo(out SYSTEM_INFO lpSystemInfo);

VB.Net Signature:

Private Declare Sub GetSystemInfo Lib "kernel32" (<MarshalAs(UnmanagedType.Struct)> ByRef lpSystemInfo As SYSTEM_INFO)

User-Defined Types:

SYSTEM_INFO

Notes:

This API mapping demonstrates mapping a union in C#.

Tips & Tricks:

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.

Sample Code:

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

Determinating CPU Version:

    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].

Alternative Managed API:

Do you know one? Please contribute it!

Documentation