Identifying the CPU architecture type using C#

37,355

Solution 1

You could also try (only works if it's not manipulated):

System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")

Solution 2

What led me here is checking for a 32 vs 64 bit OS. the highest rated answer is looking at the setting for the Current process. After not finding an answer I found the following setting. Hope this works for you.

bool is64 = System.Environment.Is64BitOperatingSystem

Solution 3

I know that this question is from the past, but as of 2017, there is now a simple method to know the architecture of the current process, in .net standard :

System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture

The value returned is one of X86, X64, ARM, ARM64 and gives the architecture of the process it's running in. OSArchitecture returns the architecture of the installed operating system instead.

Links to the docs (pretty useless though...):

RuntimeInformation.ProcessArchitecture: https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.runtimeinformation.processarchitecture?view=netstandard-1.4

Architecture enumeration: https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.architecture?view=netstandard-1.4

Solution 4

Here is a piece of code that seems to work (based on P/Invoke); It allows to determine the CPU/Machine architecture, current process architecture and also a given binary file architecture (how it's been compiled):

    public enum Architecture
    {
        Unknown,
        x86,
        x64,
        arm64,
    }

    public static Architecture ProcessArchitecture
    {
        get
        {
            var si = new SYSTEM_INFO();
            GetSystemInfo(ref si);
            return GetArchitecture(ref si);
        }
    }

    public static Architecture MachineArchitecture
    {
        get
        {
            var si = new SYSTEM_INFO();
            GetNativeSystemInfo(ref si);
            return GetArchitecture(ref si);
        }
    }

    public static Architecture ReadFileArchitecture(string filePath)
    {
        if (filePath == null)
            throw new ArgumentNullException(nameof(filePath));

        using (var stream = File.OpenRead(filePath))
        {
            return ReadFileArchitecture(stream);
        }
    }

    // note .NET dll will come out as x86
    public static Architecture ReadFileArchitecture(Stream stream)
    {
        if (stream == null)
            throw new ArgumentNullException(nameof(stream));

        var length = stream.Length;
        if (length < 64)
            return Architecture.Unknown;

        var reader = new BinaryReader(stream);
        stream.Position = 60;
        var peHeaderPtr = reader.ReadUInt32();
        if (peHeaderPtr == 0)
        {
            peHeaderPtr = 128;
        }
        if (peHeaderPtr > length - 256)
            return Architecture.Unknown;

        stream.Position = peHeaderPtr;
        var peSignature = reader.ReadUInt32();
        if (peSignature != 0x00004550) // "PE"
            return Architecture.Unknown;

        var machine = reader.ReadUInt16();
        Architecture arch;
        switch (machine)
        {
            case IMAGE_FILE_MACHINE_AMD64:
                arch = Architecture.x64;
                break;

            case IMAGE_FILE_MACHINE_I386:
                arch = Architecture.x86;
                break;

            case IMAGE_FILE_MACHINE_ARM64:
                arch = Architecture.arm64;
                break;

            default:
                return Architecture.Unknown;
        }
        return arch;
    }

    private static Architecture GetArchitecture(ref SYSTEM_INFO si)
    {
        switch (si.wProcessorArchitecture)
        {
            case PROCESSOR_ARCHITECTURE_AMD64:
                return Architecture.x64;

            case PROCESSOR_ARCHITECTURE_ARM64:
                return Architecture.arm64;

            case PROCESSOR_ARCHITECTURE_INTEL:
                return Architecture.x86;

            default:
                throw new PlatformNotSupportedException();
        }
    }

    private const int PROCESSOR_ARCHITECTURE_AMD64 = 9;
    private const int PROCESSOR_ARCHITECTURE_INTEL = 0;
    private const int PROCESSOR_ARCHITECTURE_ARM64 = 12;
    private const int IMAGE_FILE_MACHINE_ARM64 = 0xAA64;
    private const int IMAGE_FILE_MACHINE_I386 = 0x14C;
    private const int IMAGE_FILE_MACHINE_AMD64 = 0x8664;

    [DllImport("kernel32")]
    private static extern void GetSystemInfo(ref SYSTEM_INFO lpSystemInfo);

    [DllImport("kernel32")]
    private static extern void GetNativeSystemInfo(ref SYSTEM_INFO lpSystemInfo);

    [StructLayout(LayoutKind.Sequential)]
    private struct SYSTEM_INFO
    {
        public short wProcessorArchitecture;
        public short wReserved;
        public int dwPageSize;
        public IntPtr lpMinimumApplicationAddress;
        public IntPtr lpMaximumApplicationAddress;
        public IntPtr dwActiveProcessorMask;
        public int dwNumberOfProcessors;
        public int dwProcessorType;
        public int dwAllocationGranularity;
        public short wProcessorLevel;
        public short wProcessorRevision;
    }

This code supports x86, x64 and arm64 architectures and Windows XP. In modern versions of .NET you have built-in functions in the System.Runtime.InteropServices.RuntimeInformation namespace.

Solution 5

Win32_Processor WMI Class will do the job. Use MgmtClassGen.exe to generate strongly-typed wrappers.

Share:
37,355
Anirudh Goel
Author by

Anirudh Goel

I'm a CS Student. Soon going to start working. I love programming, automation, and solving PC problems.

Updated on May 15, 2020

Comments

  • Anirudh Goel
    Anirudh Goel almost 4 years

    I want to check which CPU architecture is the user running, is it i386 or X64 or AMD64. I want to do it in C#. I know i can try WMI or Registry. Is there any other way apart from these two? My project targets .NET 2.0!