¿Cómo detectar la plataforma Windows de 64 bits con .NET?

269

En una aplicación .NET 2.0 C # utilizo el siguiente código para detectar la plataforma del sistema operativo:

string os_platform = System.Environment.OSVersion.Platform.ToString();

Esto devuelve "Win32NT". El problema es que devuelve "Win32NT" incluso cuando se ejecuta en Windows Vista de 64 bits.

¿Hay algún otro método para conocer la plataforma correcta (32 o 64 bits)?

Tenga en cuenta que también debe detectar 64 bits cuando se ejecuta como una aplicación de 32 bits en Windows de 64 bits.

Bagazo
fuente

Respuestas:

200

IntPtr.Size no devolverá el valor correcto si se ejecuta en .NET Framework 2.0 de 32 bits en Windows de 64 bits (devolvería 32 bits).

Como describe Raymond Chen de Microsoft, primero debe verificar si se está ejecutando en un proceso de 64 bits (creo que en .NET puede hacerlo marcando IntPtr.Size), y si está ejecutando en un proceso de 32 bits, todavía tiene que llamar a la función Win API IsWow64Process. Si esto devuelve verdadero, está ejecutando un proceso de 32 bits en Windows de 64 bits.

Raymond Chen de Microsoft: cómo detectar mediante programación si se está ejecutando en Windows de 64 bits

Mi solución:

static bool is64BitProcess = (IntPtr.Size == 8);
static bool is64BitOperatingSystem = is64BitProcess || InternalCheckIsWow64();

[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsWow64Process(
    [In] IntPtr hProcess,
    [Out] out bool wow64Process
);

public static bool InternalCheckIsWow64()
{
    if ((Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1) ||
        Environment.OSVersion.Version.Major >= 6)
    {
        using (Process p = Process.GetCurrentProcess())
        {
            bool retVal;
            if (!IsWow64Process(p.Handle, out retVal))
            {
                return false;
            }
            return retVal;
        }
    }
    else
    {
        return false;
    }
}
Stefan Schultze
fuente
77
Cuando se ejecuta en un sistema operativo de 32 bits, cualquier llamada a IsWow64Process arrojará una excepción ya que falta esa entrada en kernel32.dll. Debe verificar la solución que se muestra en codeplex en 1code.codeplex.com/SourceControl/changeset/view/39074#842775 . También tengo una solución basada en ese código que figura en la parte inferior de esta página, que utiliza métodos de extensión si le preocupa reutilizando el código.
dmihailescu
77
IsWow64Process se introdujo con Win XP SP2. Este código funciona bien si necesita XP SP2 o cualquier versión más nueva.
Marc
3
@dmihailescu, puede usar DoesWin32MethodExist antes de llamar a IsWow64Process, que es lo que hace la implementación .net 4.0 de is64BitOperatingSystem.
noobish
44
Su solución devuelve el valor correcto en una MacBook Pro con microprocesador Intel i7-3720QM que ejecuta Bootcamp con una partición Widows 7 Ultimate. +1
Mark Kram
11
FYI: comenzando con .Net 4.0 puedes simplemente verificar System.Environment.Is64BitOperatingSystem. ¿Puedes editar esto en tu respuesta o darme permiso para editarlo en tu respuesta?
Joel Coehoorn
242

.NET 4 tiene dos nuevas propiedades en la clase de entorno, Is64BitProcess e Is64BitOperatingSystem . Curiosamente, si usa Reflector, puede ver que se implementan de manera diferente en las versiones de mscorlib de 32 y 64 bits. La versión de 32 bits devuelve falso para Is64BitProcess y llama a IsWow64Process a través de P / Invoke para Is64BitOperatingSystem. La versión de 64 bits solo devuelve verdadero para ambos.

Phil Devaney
fuente
55
En lugar de Reflector, ¿por qué no simplemente descargar la fuente? Luego obtienes los comentarios y otras "notas".
AMissico
3
Según la fuente de referencia, hace algo como esto: if (IntPtr.Size == 8) return true; if(!DoesWin32MethodExist(...,"IsWow64Process")) return false; return IsWow64Process(GetCurrentProcess());(pseudocódigo)
Polynomial
55
Agradable. Si el usuario usa .NET 4.0, esta es definitivamente la respuesta correcta (es decir, Environment.Is64BitOperatingSystem). - La propiedad FYI no parece estar allí en .NET 3.5.
BrainSlugs83
44
Esto no responde la pregunta que dice específicamente .Net 2.0
abbottdev
.NET Core se ha lanzado bajo la licencia MIT, lo que significa que puede leer el código fuente de Is64BitProcessy Is64BitOperatingSystem(enlaces para la versión 2.0).
Cristian Ciupitu
51

Esto es solo una implementación de lo sugerido anteriormente por Bruno López, pero funciona en Win2k + todos los paquetes de servicio de WinXP. Solo pensé que lo publicaría para que otras personas no lo hubieran rodado a mano. (habría publicado como comentario, ¡pero soy un nuevo usuario!)

[DllImport("kernel32", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
public extern static IntPtr LoadLibrary(string libraryName);

[DllImport("kernel32", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
public extern static IntPtr GetProcAddress(IntPtr hwnd, string procedureName);

private delegate bool IsWow64ProcessDelegate([In] IntPtr handle, [Out] out bool isWow64Process);

public static bool IsOS64Bit()
{
    if (IntPtr.Size == 8 || (IntPtr.Size == 4 && Is32BitProcessOn64BitProcessor()))
    {
        return true;
    }
    else
    {
        return false;
    }
}

private static IsWow64ProcessDelegate GetIsWow64ProcessDelegate()
{
  IntPtr handle = LoadLibrary("kernel32");

  if ( handle != IntPtr.Zero)
  {
    IntPtr fnPtr = GetProcAddress(handle, "IsWow64Process");

    if (fnPtr != IntPtr.Zero)
    {
      return (IsWow64ProcessDelegate)Marshal.GetDelegateForFunctionPointer((IntPtr)fnPtr, typeof(IsWow64ProcessDelegate));
    }
  }

  return null;
}

private static bool Is32BitProcessOn64BitProcessor()
{
  IsWow64ProcessDelegate fnDelegate = GetIsWow64ProcessDelegate();

  if (fnDelegate == null)
  {
    return false;
  }

  bool isWow64;
  bool retVal = fnDelegate.Invoke(Process.GetCurrentProcess().Handle, out isWow64);

  if (retVal == false)
  {
    return false;
  }

  return isWow64;
}
dwhiteho
fuente
49

La respuesta completa es la siguiente (tomada de stefan-mg, ripper234 y la respuesta de BobbyShaftoe):

    [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool IsWow64Process([In] IntPtr hProcess, [Out] out bool lpSystemInfo);

    private bool Is64Bit()
    {
        if (IntPtr.Size == 8 || (IntPtr.Size == 4 && Is32BitProcessOn64BitProcessor()))
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    private bool Is32BitProcessOn64BitProcessor()
    {
        bool retVal;

        IsWow64Process(Process.GetCurrentProcess().Handle, out retVal);

        return retVal;
    } 

Primero verifique si está en un proceso de 64 bits. Si no lo está, verifique si el proceso de 32 bits es un Wow64Process.

Bruno Lopes
fuente
13
Esto fallará en Win2000 y WinXP SP1 y versiones anteriores. Debe verificar si la función IsWow64Process () existe antes de llamarla, ya que solo se introdujo en XP SP2 y Vista / Win7.
user9876
2
@ user9876, ¿alguien (o lo hizo) todavía apunta a esos sistemas antiguos?
CMircea
55
Este ejemplo no puede eliminar la instancia de Process devuelta por Process.GetCurrentProcess ().
Joe
42

Microsoft ha puesto un código de muestra para esto:

http://1code.codeplex.com/SourceControl/changeset/view/39074#842775

Se parece a esto:

    /// <summary>
    /// The function determines whether the current operating system is a 
    /// 64-bit operating system.
    /// </summary>
    /// <returns>
    /// The function returns true if the operating system is 64-bit; 
    /// otherwise, it returns false.
    /// </returns>
    public static bool Is64BitOperatingSystem()
    {
        if (IntPtr.Size == 8)  // 64-bit programs run only on Win64
        {
            return true;
        }
        else  // 32-bit programs run on both 32-bit and 64-bit Windows
        {
            // Detect whether the current process is a 32-bit process 
            // running on a 64-bit system.
            bool flag;
            return ((DoesWin32MethodExist("kernel32.dll", "IsWow64Process") &&
                IsWow64Process(GetCurrentProcess(), out flag)) && flag);
        }
    }

    /// <summary>
    /// The function determins whether a method exists in the export 
    /// table of a certain module.
    /// </summary>
    /// <param name="moduleName">The name of the module</param>
    /// <param name="methodName">The name of the method</param>
    /// <returns>
    /// The function returns true if the method specified by methodName 
    /// exists in the export table of the module specified by moduleName.
    /// </returns>
    static bool DoesWin32MethodExist(string moduleName, string methodName)
    {
        IntPtr moduleHandle = GetModuleHandle(moduleName);
        if (moduleHandle == IntPtr.Zero)
        {
            return false;
        }
        return (GetProcAddress(moduleHandle, methodName) != IntPtr.Zero);
    }

    [DllImport("kernel32.dll")]
    static extern IntPtr GetCurrentProcess();

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr GetModuleHandle(string moduleName);

    [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]
    static extern IntPtr GetProcAddress(IntPtr hModule,
        [MarshalAs(UnmanagedType.LPStr)]string procName);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process);

También hay una versión WMI disponible (para probar máquinas remotas).

synhershko
fuente
1
Tenga en cuenta que este código tiene licencia bajo la Licencia pública de Microsoft .
ladenedge
¿Versión WMI sin .net administrado? Me gustaría ver eso, no lo he encontrado hasta ahora
JohnZaj
16

También puede verificar la PROCESSOR_ARCHITECTUREvariable de entorno.

No existe o está configurado en "x86" en Windows de 32 bits.

private int GetOSArchitecture()
{
    string pa = 
        Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE");
    return ((String.IsNullOrEmpty(pa) || 
             String.Compare(pa, 0, "x86", 0, 3, true) == 0) ? 32 : 64);
}
Andrew Ensley
fuente
1
El hecho de que tenga un procesador de 64 bits no significa que tenga un sistema operativo de 64 bits
David
2
@David Esto informa la arquitectura del procesador de Windows; No la CPU. Consulte la explicación detallada que comienza en "El Código" en esta página: andrewensley.com/2009/06/c-detect-windows-os-part-1
Andrew Ensley
Sólo para añadir 2 centavos, al ejecutar esto, y su aplicación está configurado para prefer 32-bitcon Any CPUcomo su Platform Targetpor lo que recibirá x86, pero si no marcas Prefer 32-bitque a continuación, recibirá AMD64.
XAMlMAX
14

Del blog de Chriz Yuen

C # .Net 4.0 introdujo dos nuevas propiedades de entorno Environment.Is64BitOperatingSystem; Environment.Is64BitProcess;

Tenga cuidado cuando use estas dos propiedades. Prueba en Windows 7 64bits Machine

//Workspace: Target Platform x86
Environment.Is64BitOperatingSystem True
Environment.Is64BitProcess False

//Workspace: Target Platform x64
Environment.Is64BitOperatingSystem True
Environment.Is64BitProcess True

//Workspace: Target Platform Any
Environment.Is64BitOperatingSystem True
Environment.Is64BitProcess True
electricbah
fuente
12

La manera mas rapida:

if(IntPtr.Size == 8) {
    // 64 bit machine
} else if(IntPtr.Size == 4)  {
    // 32 bit machine
} 

Nota: esto es muy directo y funciona correctamente en 64 bits solo si el programa no fuerza la ejecución como un proceso de 32 bits (por ejemplo,<Prefer32Bit>true</Prefer32Bit>en la configuración del proyecto).

BobbyShaftoe
fuente
32
Esto no funcionará: si se ejecuta en .NET Framework 2.0 de 32 bits en Windows de 64 bits, devolverá 32 bits.
Stefan Schultze
Bien, olvidé esta situación. He editado la pregunta para mencionar esto también. Gracias stefan-mg.
Marc
1
Esto no es correcto; la plataforma puede ser de 64 bits pero aún se está ejecutando en modo de 32 bits.
Sebastian Good
11

Prueba esto:

Environment.Is64BitOperatingSystem

Environment.Is64BitProcess
usuario2235582
fuente
55
Gracias por su aporte, pero lea las respuestas disponibles antes de publicar, ya que esta solución ya está disponible. También tenga en cuenta que la pregunta original era sobre .net 2 que no tiene estas dos propiedades que se introdujeron solo con .net 4.
Marc
9

@foobar: Tienes razón, es demasiado fácil;)

En el 99% de los casos, los desarrolladores con antecedentes débiles de administrador del sistema finalmente no se dan cuenta del poder que Microsoft siempre ha brindado a cualquiera para enumerar Windows.

Los administradores del sistema siempre escribirán un código mejor y más simple cuando se trata de tal punto.

Sin embargo, una cosa a tener en cuenta, la configuración de compilación debe ser AnyCPU para que esta variable de entorno devuelva los valores correctos en los sistemas correctos:

System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")

Esto devolverá "X86" en Windows de 32 bits y "AMD64" en Windows de 64 bits.

SomeSysadmin
fuente
44
Su solución devuelve x86 en una MacBook Pro con microprocesador Intel i7-3720QM que ejecuta Bootcamp con una partición Widows 7 Ultimate. La solución de Stefan Schultze identificó correctamente el procesador como de 64 bits. Estoy seguro de que su solución funciona en el 99% de las PC basadas en Windows que existen. +1 por intentarlo.
Mark Kram
No devolvió "x86" en mi sistema operativo Windows 7 pro de 64 bits.
Hagai L
7

Usar dotPeek ayuda a ver cómo lo hace realmente el marco. Con eso en mente, esto es lo que se me ocurrió:

public static class EnvironmentHelper
{
    [DllImport("kernel32.dll")]
    static extern IntPtr GetCurrentProcess();

    [DllImport("kernel32.dll")]
    static extern IntPtr GetModuleHandle(string moduleName);

    [DllImport("kernel32")]
    static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

    [DllImport("kernel32.dll")]
    static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process);

    public static bool Is64BitOperatingSystem()
    {
        // Check if this process is natively an x64 process. If it is, it will only run on x64 environments, thus, the environment must be x64.
        if (IntPtr.Size == 8)
            return true;
        // Check if this process is an x86 process running on an x64 environment.
        IntPtr moduleHandle = GetModuleHandle("kernel32");
        if (moduleHandle != IntPtr.Zero)
        {
            IntPtr processAddress = GetProcAddress(moduleHandle, "IsWow64Process");
            if (processAddress != IntPtr.Zero)
            {
                bool result;
                if (IsWow64Process(GetCurrentProcess(), out result) && result)
                    return true;
            }
        }
        // The environment must be an x86 environment.
        return false;
    }
}

Ejemplo de uso:

EnvironmentHelper.Is64BitOperatingSystem();
Alexandru
fuente
6

Use estas dos variables de entorno (pseudocódigo):

if (PROCESSOR_ARCHITECTURE = x86 &&
    isDefined(PROCESSOR_ARCHITEW6432) &&
    PROCESSOR_ARCHITEW6432 = AMD64) {

    //64 bit OS
}
else
    if (PROCESSOR_ARCHITECTURE = AMD64) {
        //64 bit OS
    }
    else
        if (PROCESSOR_ARCHITECTURE = x86) {
            //32 bit OS
        }

Consulte la publicación del blog CÓMO: Detectar Bitness de proceso .

Santhosh
fuente
¿Viste la parte donde la pregunta era sobre .NET y no sobre C / C ++? Y que este es un tiempo de compilación versus una verificación de tiempo de ejecución. Además, el código está haciendo asignaciones y no comparaciones.
dvallejo
Este código funciona en .NET (probado en 2.0). Se puede acceder a las variables Env mediante: Environment.GetEnvironmentVariable ("PROCESSOR_ARCHITECTURE"); Environment.GetEnvironmentVariable ("PROCESSOR_ARCHITEW6432");
andrew.fox
5

Utilicé esta comprobación con éxito en muchos sistemas operativos:

private bool Is64BitSystem
{
   get
   {
      return Directory.Exists(Environment.ExpandEnvironmentVariables(@"%windir%\SysWOW64"));
   }
}

Esta carpeta siempre se llama "SysWOW64", sin importar el idioma del sistema operativo. Esto funciona para .NET Framework 1.1 o superior.

Alexandru Dicu
fuente
¿Y qué me impide como usuario con derechos administrativos crear una carpeta llamada SysWOW64en un %windir%sistema operativo de 32 bits? La presencia de una carpeta significa exactamente eso: que la carpeta está presente.
cogumel0
¿Qué posibilidades hay de que un usuario cree dicha carpeta a propósito? Esta es solo una forma diferente de verificar si el sistema operativo es x64.
Alexandru Dicu
¿Cuáles son las posibilidades de que su computadora obtenga un virus? Dado que las posibilidades son bastante bajas, mejor no instale ninguna protección entonces ... La programación no se trata de crear algo que tenga pocas posibilidades de fallar a sabiendas . Se trata de crear algo que tenga pocas posibilidades de fallar sin saberlo , y luego solucionarlo. El primero se llama mala programación / mala implementación, el segundo se llama error.
cogumel0
@AlexandruDicu Debería mencionar en la respuesta que este enfoque no es 100% exacto y aún corre el riesgo de dar un resultado incorrecto en caso de que la carpeta sea creada a propósito por cualquier aplicación de terceros o usuario manualmente.
Rajesh Mishra
4

Necesito hacer esto, pero también necesito poder como administrador hacerlo de forma remota, en cualquier caso, esto parece funcionar bastante bien para mí:

    public static bool is64bit(String host)
    {
        using (var reg = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, host))
        using (var key = reg.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\"))
        {
            return key.GetValue("ProgramFilesDir (x86)") !=null;
        }
    }
Julian Hall
fuente
4

Esta es una solución basada en el código de Microsoft en http://1code.codeplex.com/SourceControl/changeset/view/39074#842775 . Utiliza métodos de extensión para reutilizar fácilmente el código.

Algunos usos posibles se muestran a continuación:

bool bIs64BitOS = System.Environment.OSVersion.IsWin64BitOS();

bool bIs64BitProc = System.Diagnostics.Process.GetCurrentProcess().Is64BitProc();

//Hosts the extension methods  
public static class OSHelperTools  
{  
    /// <summary>     
    /// The function determines whether the current operating system is a      
    /// 64-bit operating system.     
    /// </summary>     
    /// <returns>     
    /// The function returns true if the operating system is 64-bit;      
    /// otherwise, it returns false.     
    /// </returns>    
    public static bool IsWin64BitOS(this OperatingSystem os)  
    {  
        if (IntPtr.Size == 8)  
        // 64-bit programs run only on Win64           
            return true;   
        else// 32-bit programs run on both 32-bit and 64-bit Windows     
        {   // Detect whether the current process is a 32-bit process                
            // running on a 64-bit system.               
            return Process.GetCurrentProcess().Is64BitProc();  
        }  
    }  

    /// <summary>  
    /// Checks if the process is 64 bit  
    /// </summary>  
    /// <param name="os"></param>  
    /// <returns>  
    /// The function returns true if the process is 64-bit;        
    /// otherwise, it returns false.  
    /// </returns>    
    public static bool Is64BitProc(this System.Diagnostics.Process p)  
    {  
        // 32-bit programs run on both 32-bit and 64-bit Windows           
        // Detect whether the current process is a 32-bit process                
        // running on a 64-bit system.               
        bool result;  
        return ((DoesWin32MethodExist("kernel32.dll", "IsWow64Process") && IsWow64Process(p.Handle, out result)) && result);  
    }  

    /// <summary>     
    /// The function determins whether a method exists in the export      
    /// table of a certain module.     
    /// </summary>     
    /// <param name="moduleName">The name of the module</param>     
    /// <param name="methodName">The name of the method</param>     
    /// <returns>     
    /// The function returns true if the method specified by methodName      
    /// exists in the export table of the module specified by moduleName.     
    /// </returns>       
    static bool DoesWin32MethodExist(string moduleName, string methodName)  
    {  
        IntPtr moduleHandle = GetModuleHandle(moduleName);  
        if (moduleHandle == IntPtr.Zero)  
            return false;    
        return (GetProcAddress(moduleHandle, methodName) != IntPtr.Zero);   
    }  
    [DllImport("kernel32.dll")]  
    static extern IntPtr GetCurrentProcess();  

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]  
    static extern IntPtr GetModuleHandle(string moduleName);  

    [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]  
    static extern IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)]string procName);  

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]  
    [return: MarshalAs(UnmanagedType.Bool)]  
    static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process);  
}
dmihailescu
fuente
El enlace CodePlex parece estar roto.
Peter Mortensen
3

Aquí está el enfoque directo en C # usando DllImport de esta página .

[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)] 
[return: MarshalAs(UnmanagedType.Bool)] 
public static extern bool IsWow64Process([In] IntPtr hProcess, [Out] out bool lpSystemInfo); 

public static bool Is64Bit() 
{ 
    bool retVal; 

    IsWow64Process(Process.GetCurrentProcess().Handle, out retVal); 

    return retVal; 
} 
ripper234
fuente
Todavía debe verificar primero el tamaño del puntero, de lo contrario, solo verifica si es un proceso de 32 bits en un sistema de 64 bits
Bruno Lopes,
1
También se bloquea en un sistema operativo anterior, ya IsWow64Processque no existe.
Polinómico
3

Estoy usando el siguiente código. Nota: Está hecho para un proyecto AnyCPU.

    public static bool Is32bitProcess(Process proc) {
        if (!IsThis64bitProcess()) return true; // We're in 32-bit mode, so all are 32-bit.

        foreach (ProcessModule module in proc.Modules) {
            try {
                string fname = Path.GetFileName(module.FileName).ToLowerInvariant();
                if (fname.Contains("wow64")) {
                    return true;
                }
            } catch {
                // What on earth is going on here?
            }
        }
        return false;
    }

    public static bool Is64bitProcess(Process proc) {
        return !Is32bitProcess(proc);
    }

    public static bool IsThis64bitProcess() {
        return (IntPtr.Size == 8);
    }
blez
fuente
2

Encontré que esta es la mejor manera de verificar la plataforma del sistema y el proceso:

bool 64BitSystem = Environment.Is64BitOperatingSystem;
bool 64BitProcess = Environment.Is64BitProcess;

La primera propiedad devuelve verdadero para el sistema de 64 bits y falso para el de 32 bits. La segunda propiedad devuelve verdadero para el proceso de 64 bits y falso para el de 32 bits.

La necesidad de estas dos propiedades se debe a que puede ejecutar procesos de 32 bits en un sistema de 64 bits, por lo que deberá verificar tanto el sistema como el proceso.

OmarElsherif
fuente
1
ponga una _ o una letra delante del nombre de la variable si desea que se construya en c # (¡los nombres de las variables no comienzan con números en c # hasta donde mi ide me lo dice!)
Chris
2

Todo bien, pero esto también debería funcionar desde env:

PROCESSOR_ARCHITECTURE=x86

..

PROCESSOR_ARCHITECTURE=AMD64

Demasiado fácil, tal vez ;-)

Peter Mortensen
fuente
2

Aquí está un enfoque de Instrumental de administración de Windows (WMI):

string _osVersion = "";
string _osServicePack = "";
string _osArchitecture = "";

ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from Win32_OperatingSystem");
ManagementObjectCollection collection = searcher.Get();

foreach (ManagementObject mbo in collection)
{
    _osVersion = mbo.GetPropertyValue("Caption").ToString();
    _osServicePack = string.Format("{0}.{1}", mbo.GetPropertyValue("ServicePackMajorVersion").ToString(), mbo.GetPropertyValue("ServicePackMinorVersion").ToString());

    try
    {
        _osArchitecture = mbo.GetPropertyValue("OSArchitecture").ToString();
    }
    catch
    {
        // OSArchitecture only supported on Windows 7/Windows Server 2008
    }
}

Console.WriteLine("osVersion     : " + _osVersion);
Console.WriteLine("osServicePack : " + _osServicePack);
Console.WriteLine("osArchitecture: " + _osArchitecture);

/////////////////////////////////////////
// Test on Windows 7 64-bit
//
// osVersion     : Microsoft Windows 7 Professional
// osservicePack : 1.0
// osArchitecture: 64-bit

/////////////////////////////////////////
// Test on Windows Server 2008 64-bit
//    --The extra r's come from the registered trademark
//
// osVersion     : Microsoftr Windows Serverr 2008 Standard
// osServicePack : 1.0
// osArchitecture: 64-bit

/////////////////////////////////////////
// Test on Windows Server 2003 32-bit
//    --OSArchitecture property not supported on W2K3
//
// osVersion     : Microsoft(R) Windows(R) Server 2003, Standard Edition
// osServicePack : 2.0
// osArchitecture:
usuario1054695
fuente
1

OSInfo.Bits

using System;
namespace CSharp411
{
    class Program
    {
        static void Main( string[] args )
        {
           Console.WriteLine( "Operation System Information" );
           Console.WriteLine( "----------------------------" );
           Console.WriteLine( "Name = {0}", OSInfo.Name );
           Console.WriteLine( "Edition = {0}", OSInfo.Edition );
           Console.WriteLine( "Service Pack = {0}", OSInfo.ServicePack );
           Console.WriteLine( "Version = {0}", OSInfo.VersionString );
           Console.WriteLine( "Bits = {0}", OSInfo.Bits );
           Console.ReadLine();
        }
    }
}
Greg
fuente
3
Eso está bien, pero esta clase es de Microsoft.UpdateServices.Administration namespace que es Microsoft WSUS. No me gusta incluir esta referencia solo para conocer los bits de la plataforma.
Marc
"C: \ Archivos de programa \ Microsoft.NET \ SDK \ v2.0 64bit \ LateBreaking \ PlatformInvoke \ WinAPIs \ OSInfo \ CS \ OSInfoCS.sln"
AMissico
1

Incluya el siguiente código en una clase en su proyecto:

    [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool IsWow64Process([In] IntPtr hProcess, [Out] out bool wow64Process);

    public static int GetBit()
    {
        int MethodResult = "";
        try
        {
            int Architecture = 32;

            if ((Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1) || Environment.OSVersion.Version.Major >= 6)
            {
                using (Process p = Process.GetCurrentProcess())
                {
                    bool Is64Bit;

                    if (IsWow64Process(p.Handle, out Is64Bit))
                    {
                        if (Is64Bit)
                        {
                            Architecture = 64;

                        }

                    }

                }

            }

            MethodResult = Architecture;

        }
        catch //(Exception ex)
        {
            //ex.HandleException();
        }
        return MethodResult;
    }

Úselo así:

string Architecture = "This is a " + GetBit() + "bit machine";
WonderWorker
fuente
0

Use esto para obtener la arquitectura de Windows instalada:

string getOSArchitecture()
{
    string architectureStr;
    if (Directory.Exists(Environment.GetFolderPath(
                           Environment.SpecialFolder.ProgramFilesX86))) {
        architectureStr ="64-bit";
    }
    else {
        architectureStr = "32-bit";
    }
    return architectureStr;
}
usuario885959
fuente
no tengo una propiedad ProgramFilesX86 en w7x64 vs.net 2010
Christian
0

Dado que la respuesta aceptada es muy compleja. Hay formas mas simples. El mío es una variación de la respuesta de alexandrudicu. Dado que las ventanas de 64 bits instalan aplicaciones de 32 bits en Archivos de programa (x86), puede verificar si esa carpeta existe, utilizando variables de entorno (para compensar las diferentes localizaciones)

p.ej

private bool Is64BitSystem
{
   get
   {
      return Directory.Exists(Environment.ExpandEnvironmentVariables(@"%PROGRAMFILES(X86)%"));
   }
}

Esto para mí es más rápido y sencillo. Dado que también deseo acceder a una ruta específica en esa carpeta según la versión del sistema operativo.

John Demetriou
fuente
2
La respuesta aceptada fue para .NET 2.0. Si estás en .NET 4.0 o más reciente, solo usa Environment.Is64BitOperatingSystem como puedes encontrar en la respuesta con la mayoría de los votos.
Marc
Sí, el mío también es para .net 2.0.
John Demetriou
-2

Disfruta ;-)

Function Is64Bit() As Boolean

    Return My.Computer.FileSystem.SpecialDirectories.ProgramFiles.Contains("Program Files (x86)")

End Function
Majid95
fuente
-1 ya que esto no funcionará en instalaciones localizadas de Windows. Y usa VB.net, mientras que la pregunta está etiquetada para C #.
Marc
-3

Solo vea si existe el "C: \ Archivos de programa (x86)". Si no, entonces estás en un sistema operativo de 32 bits. Si lo hace, entonces el sistema operativo es de 64 bits (Windows Vista o Windows 7). Parece bastante simple ...

Juan
fuente
55
Asegúrese de recuperar el nombre de directorio localizado correcto de la API de Win32 en lugar de codificarlo.
Christian Hayter
Diría que es una buena idea, pero no puedes asumir que un usuario nunca haría esto por alguna razón oscura.
GurdeepS
2
Algunas aplicaciones mal escritas ahora se instalan directamente en "Archivos de programa (x86)" sin importar la arquitectura. Tengo ese directorio en mi máquina de 32 bits gracias a SOAPSonar, por ejemplo.
ladenedge
-4

Yo suelo:

Dim drivelet As String = Application.StartupPath.ToString
If Directory.Exists(drivelet(0) & ":\Program Files (x86)") Then
    MsgBox("64bit")
Else
    MsgBox("32bit")
End if

Esto obtiene la ruta donde se inicia su aplicación en caso de que la tenga instalada en varios lugares de la computadora. Además, podría hacer la C:\ruta general ya que el 99.9% de las computadoras tienen Windows instalado C:\.

Ben G
fuente
8
Muy mal enfoque. ¿Qué pasa si en el futuro se cambiará el nombre de este directorio? ¿Qué pasa con la versión localizada de Windows? En Windows XP, los "Archivos de programa" alemanes se denominan "Programa". No estoy seguro, pero XP 64 puede llamarlo "Programa (x86)".
Marc
1
No lo recomiendo, pero podría solucionar el problema de localización expandiendo la var. Ambiental% ProgramFiles (x86)%
Matthew Lock
-7

Yo uso una versión de lo siguiente:

    public static bool Is64BitSystem()
    {
        if (Directory.Exists(Environment.GetEnvironmentVariable("Program Files (x86)"))) return true;
        else return false;
    }
Josh
fuente
66
Esto no funciona en versiones de XP que no están en inglés debido al nombre de carpetas de programa localizado.
Daniel Schlößer
Pero incluso los sistemas de 64 bits tienen esta carpeta jaja
cuidado