Identifying the CPU architecture type using C#

一世执手 提交于 2019-11-27 09:02:45

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

System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")

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

Here is a piece of code that seems to work (based on P/Invoke):

    public static ProcessorArchitecture GetProcessorArchitecture()
    {
        SYSTEM_INFO si = new SYSTEM_INFO();
        GetNativeSystemInfo(ref si);
        switch (si.wProcessorArchitecture)
        {
            case PROCESSOR_ARCHITECTURE_AMD64:
                return ProcessorArchitecture.Amd64;

            case PROCESSOR_ARCHITECTURE_IA64:
                return ProcessorArchitecture.IA64;

            case PROCESSOR_ARCHITECTURE_INTEL:
                return ProcessorArchitecture.X86;

            default:
                return ProcessorArchitecture.None; // that's weird :-)
        }
    }

with

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

    private const int PROCESSOR_ARCHITECTURE_AMD64 = 9;
    private const int PROCESSOR_ARCHITECTURE_IA64 = 6;
    private const int PROCESSOR_ARCHITECTURE_INTEL = 0;

    [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;
    }

Note this code reuses the existing CLR's ProcessorArchitecture enum, and supports .NET framework 2 and higher.

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

Finally the shortest trick to resolve the platform/processor architecture for the current running CLR runtime in C# is:

PortableExecutableKinds peKind;
ImageFileMachine machine;
typeof(object).Module.GetPEKind(out peKind, out machine);

Here Module.GetPEKind returns an ImageFileMachine enumeration, which exists since .NET v2:

public enum ImageFileMachine
{
    I386    = 0x014C,
    IA64    = 0x0200,
    AMD64   = 0x8664,
    ARM     = 0x01C4    // new in .NET 4.5
}

Why not use new AssemblyName(fullName) or typeof(object).Assembly.GetName()?
Well there is this HACK comment in ASP.NET MVC source code (since 1.0):

private static string GetMvcVersionString() {
    // DevDiv 216459:
    // This code originally used Assembly.GetName(), but that requires FileIOPermission, which isn't granted in
    // medium trust. However, Assembly.FullName *is* accessible in medium trust.
    return new AssemblyName(typeof(MvcHttpHandler).Assembly.FullName).Version.ToString(2);
}

See they use some hidden tricks for themselves. Sadly, the AssemblyName constructor doesn't set the ProcessorArchitecture field appropriately, it's just None for whatever new AssemblyName.

So for future readers, let me recommend you using that ugly GetPEKind with ImageFileMachine!

Notes:

  • This returns the current running runtime architecture, not the underlying system architecture!
    That said, the only exception is that an I386 runtime may run on an AMD64 system.
  • Tested on mono/ubuntu 14.04/AMD64 and .NET/Win7/I386.

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

Maybe this CodeProject article could help? It uses the ManagementObjectSearcher in the System.Management namespace to search for hardware info.

Depending on why you want to know, you might find that checking the size of the IntPtr structure is the easiest way.

You could ask the user perhaps?

Just kidding of course... I think WMI is what you would use for that. But maybe there is some other way as well?

If you go for WMI then LinqToWmi could be of use. I tried it out once, and it seemed pretty straight forward =) -> http://www.codeplex.com/linq2wmi

I believe you should avoid heavy bloat like WMI and LINQ.. and you'll have to eventually, to get more info as you go along, none of which are satisfied by bloated apis and frameworks.

Just invoke a dll that calls and extracts CPUID info. C++/CLI or pinvoke would do and get all the info you need on the vendor. First you need to see whether the instruction is supported (99% of the time it is).

To get quickly up and running is to check the intel site for wincpuid sample and extract the piece from cpuid.h from there. There are only 2 vendors and one is good with memory latency and the other one isn't (like native vs managed code). So you'll have issues with Mono on other architectures etc (who doesn't btw). As for x64 you already know it or just get the corflags (its there already and killing your customer hard drive with .NET distribution )..

(http://software.intel.com/en-us/articles/api-detects-ia-32-and-x64-platform-cpu-characteristics/)

This seems the simplest to me:

System.Environment.Is64BitOperatingSystem

How about this?

switch (typeof(string).Assembly.GetName().ProcessorArchitecture) {
    case System.Reflection.ProcessorArchitecture.X86:
        break;
    case System.Reflection.ProcessorArchitecture.Amd64:
        break;
    case System.Reflection.ProcessorArchitecture.Arm:
        break;
}

However case *.Arm: isn't tested yet.

Here's what I did:

public static bool Isx86()
{
    return (Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%").Length == 0);
}

If you're on 64 bit architecture you'll have two program file env variables. If you're on x86, you'll only have the one.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!