tipos - Identificando el tipo de arquitectura de la CPU usando C#
problemas resueltos de arquitectura de computadores pdf (13)
Quiero comprobar qué arquitectura de la CPU está ejecutando el usuario, es i386 o X64 o AMD64. Quiero hacerlo en C #. Sé que puedo probar WMI o Registro. ¿Hay alguna otra manera aparte de estos dos? ¡Mi proyecto apunta a .NET 2.0!
¿Podrías preguntarle al usuario tal vez?
Solo bromeo, por supuesto ... Creo que WMI es lo que usarías para eso. Pero tal vez hay alguna otra manera también?
Si eliges WMI, entonces LinqToWmi podría ser de utilidad. Lo probé una vez, y me pareció bastante sencillo =) -> http://www.codeplex.com/linq2wmi
¿Qué tal esto?
switch (typeof(string).Assembly.GetName().ProcessorArchitecture) {
case System.Reflection.ProcessorArchitecture.X86:
break;
case System.Reflection.ProcessorArchitecture.Amd64:
break;
case System.Reflection.ProcessorArchitecture.Arm:
break;
}
Sin embargo, el case *.Arm:
no se ha probado todavía.
Aquí hay un fragmento de código que parece funcionar (basado en 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 :-)
}
}
con
[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;
}
Tenga en cuenta que este código reutiliza la enumeración de arquitectura de ProcessorArchitecture de CLR existente y es compatible con .NET framework 2 y superior.
Creo que deberías evitar la hinchazón pesada como WMI y LINQ ... y, eventualmente, tendrás que obtener más información a medida que avanzas, ninguna de las cuales está satisfecha por apis y marcos hinchados.
Simplemente invoca una dll que llama y extrae información de CPUID. C ++ / CLI o pinvoke haría y obtendría toda la información que necesita sobre el proveedor. Primero debe ver si la instrucción es compatible (el 99% del tiempo es compatible).
Para ponerse en marcha rápidamente es revisar el sitio de Intel para obtener una muestra de wincpuid y extraer la pieza de cpuid.h desde allí. Solo hay 2 proveedores y uno es bueno con la latencia de la memoria y el otro no (como el código nativo o el código administrado). Así que tendrás problemas con Mono en otras arquitecturas, etc. (quién no lo hace por cierto). En cuanto a x64, ya lo sabes o simplemente obtienes los corflags (ya está ahí y está matando a tu disco duro de cliente con distribución .NET)
( http://software.intel.com/en-us/articles/api-detects-ia-32-and-x64-platform-cpu-characteristics/ )
Dependiendo de por qué quiere saber, puede encontrar que verificar el tamaño de la estructura IntPtr es la forma más fácil.
Esto es lo que hice:
public static bool Isx86()
{
return (Environment.ExpandEnvironmentVariables("%ProgramFiles(x86)%").Length == 0);
}
Si está en la arquitectura de 64 bits, tendrá dos variables env de archivos de programa. Si estás en x86, solo tendrás una.
Esto me parece lo más simple:
System.Environment.Is64BitOperatingSystem
Finalmente, el truco más corto para resolver la arquitectura de plataforma / procesador para el tiempo de ejecución de CLR en ejecución actual en C # es:
PortableExecutableKinds peKind;
ImageFileMachine machine;
typeof(object).Module.GetPEKind(out peKind, out machine);
Aquí Module.GetPEKind devuelve una enumeración ImageFileMachine , que existe desde .NET v2:
public enum ImageFileMachine
{
I386 = 0x014C,
IA64 = 0x0200,
AMD64 = 0x8664,
ARM = 0x01C4 // new in .NET 4.5
}
¿Por qué no usar el new AssemblyName(fullName)
o typeof(object).Assembly.GetName()
?
Bueno, hay un comentario HACK
en el código fuente de ASP.NET MVC (desde la versión 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);
}
Ver que usan algunos trucos ocultos para ellos mismos. Lamentablemente, el constructor de AssemblyName
no establece el campo ProcessorArchitecture
apropiadamente, es simplemente None
para cualquier nuevo AssemblyName.
¡Así que para futuros lectores, permítame recomendarle que use ese feo GetPEKind con ImageFileMachine!
Notas:
- ¡Esto devuelve la arquitectura de ejecución actual, no la arquitectura del sistema subyacente!
Dicho esto, la única excepción es que un tiempo de ejecución I386 puede ejecutarse en un sistema AMD64. - Probado en mono / ubuntu 14.04 / AMD64 y .NET / Win7 / I386.
Lo que me llevó aquí es la comprobación de un sistema operativo de 32 vs 64 bits. La respuesta con la calificación más alta es observar la configuración del proceso actual . Después de no encontrar una respuesta encontré la siguiente configuración. Espero que esto funcione para usted.
bool is64 = System.Environment.Is64BitOperatingSystem
Sé que esta pregunta es del pasado, pero a partir de 2017, ahora existe un método simple para conocer la arquitectura del proceso actual, en el estándar .net:
System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture
El valor devuelto es uno de X86, X64, ARM, ARM64 y proporciona la arquitectura del proceso en el que se está ejecutando. OSArchitecture
devuelve la arquitectura del sistema operativo instalado.
Enlaces a los documentos (bastante inútil aunque ...):
RuntimeInformation.ProcessArchitecture: https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.runtimeinformation.processarchitecture?view=netstandard-1.4
Enumeración de la arquitectura: https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.architecture?view=netstandard-1.4
Tal vez this artículo de CodeProject podría ayudar? Utiliza ManagementObjectSearcher en el espacio de nombres System.Management para buscar información de hardware.
También puedes probar (solo funciona si no está manipulado):
System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")
Win32_Processor WMI Class hará el trabajo. Use MgmtClassGen.exe para generar envoltorios fuertemente tipados.