Identifying the CPU architecture type using C#

前端 未结 14 2311
心在旅途
心在旅途 2020-12-01 17:52

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

14条回答
  •  感情败类
    2020-12-01 18:30

    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.

提交回复
热议问题