2008-12-03 14 views
237

En un 2,0 C aplicación .NET # utilizo el siguiente código para detectar la plataforma de sistema operativo:¿Cómo detectar la plataforma de Windows de 64 bits con .NET?

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   bit)?

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

Respuesta

185

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 Microsoft Raymond Chen, primero debe comprobar si se ejecuta en un proceso de 64 bits (creo que en .NET puede hacerlo al marcar IntPtr.Size), y si está ejecutando en un 32 bits proceso, aún debe llamar a la función Win API IsWow64Process. Si esto devuelve verdadero, se está ejecutando en un proceso de 32 bits en Windows de 64 bits.

de Microsoft Raymond Chen: How to detect programmatically whether you are running on 64-bit Windows

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

Cuando se ejecuta en un sistema operativo de 32 bits, cualquier llamada a IsWow64Process arrojará una excepción ya que esa entrada falta en kernel32.dll. Debería verificar la solución que se muestra en codeplex en http://1code.codeplex.com/SourceControl/changeset/view/39074#842775. También tengo una solución basada en el código que aparece en la parte inferior de esta página, que usa métodos de extensión. si te importa reutilizar el código – dmihailescu

+7

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 de .64 de is64BitOperatingSystem. – noobish

7

manera más rápida:

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

Nota: esto es muy directa.

+0

Ahora me siento estúpido ... Podría haberle ocurrido eso ;-) Muchas gracias. – Marc

+30

Esto no funcionará: si se ejecuta en .NET Framework 2.0 de 32 bits en Windows de 64 bits, devolverá 32 bits. –

+0

Derecha Olvidé esta situación. He editado la pregunta para mencionar esto también. Gracias stefan-mg. – Marc

3

Aquí es el enfoque directo en C# usando DllImport de this page.

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

Todavía necesita verificar primero el tamaño del puntero, de lo contrario solo comprueba si se trata de un proceso de 32 bits en un sistema de 64 bits –

+1

También se bloquea en un sistema operativo anterior, ya que 'IsWow64Process' no existe. – Polynomial

47

La respuesta completa es la siguiente (tomado de ambos 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; 
    } 

En primer lugar comprobar si se encuentra en un proceso de 64 bits. Si no lo está, verifique si el proceso de 32 bits es un proceso Wow64.

+13

Esto fallará en Win2000 y WinXP SP1 y versiones anteriores.Debe comprobar si la función IsWow64Process() existe antes de llamarla, ya que solo se introdujo en XP SP2 y Vista/Win7. – user9876

+1

@ user9876, ¿sigue (o todavía lo hace) alguien apuntando a esos sistemas antiguos? – CMircea

+5

Buena pena, ¿dónde está la respuesta "correcta"? – tofutim

16

También puede verificar la variable de entorno PROCESSOR_ARCHITECTURE.

O 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); 
} 
+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 "The Code" en esta página: http://andrewensley.com/2009/06/c-detect-windows-os-part-1/ –

2

Todo bien, pero esto también se debe trabajar desde env:

PROCESSOR_ARCHITECTURE=x86 

..

PROCESSOR_ARCHITECTURE=AMD64 

Demasiado fácil, tal vez ;-)

50

esto es sólo una implementación de lo sugerido anteriormente por Bruno Lopez, pero funciona en Win2k + todos los paquetes de servicio de WinXP.Pensé que lo publicaría para que otras personas no lo hayan enrollado a mano. (Hubiera publicado como un comentario, pero yo 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; 
} 
+1

Este es el verdadero ganador, yo soy. ¡Gracias por la publicacion! – ladenedge

220

.NET 4 tiene dos nuevas propiedades de la clase Medio Ambiente, Is64BitProcess y Is64BitOperatingSystem. Curiosamente, si utiliza Reflector puede ver que se implementan de forma diferente en las versiones de 32 bits de & de 64 bits de mscorlib. La versión de 32 bits devuelve false para Is64BitProcess y llama a IsWow64Process a través de P/Invoke para Is64BitOperatingSystem. La versión de 64 bits simplemente devuelve verdadero para ambos.

+5

En lugar de Reflector, ¿por qué no descargar la fuente? Luego recibes los comentarios y otras "notas". – AMissico

+22

http://referencesource.microsoft.com/ – AMissico

+3

De acuerdo con la fuente de referencia, hace algo como esto: 'if (IntPtr.Size == 8) return true; if (! DoesWin32MethodExist (..., "IsWow64Process")) devuelve falso; return IsWow64Process (GetCurrentProcess()); '(pseudo-código) – Polynomial

6

Use estas dos variables de entorno (pseudo có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 entrada del blog HOWTO: Detect Process Bitness.

+0

¿Has visto la parte donde la pregunta era sobre .NET y no C/C++? Y que este es un tiempo de compilación frente a un control de tiempo de ejecución. Además, el código está haciendo asignación y no comparaciones. – dvallejo

+0

Este código funciona en .NET (probado en 2.0). Se puede acceder a las variables Env a través de: Environment.GetEnvironmentVariable ("PROCESSOR_ARCHITECTURE"); Environment.GetEnvironmentVariable ("PROCESSOR_ARCHITEW6432"); –

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(); 
     } 
    } 
} 
+3

Eso está muy 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

+0

"C: \ Archivos de programa \ Microsoft.NET \ SDK \ v2.0 64bit \ LateBreaking \ PlatformInvoke \ WinAPIs \ OSInfo \ CS \ OSInfoCS.sln" – AMissico

40

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

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

Parece que este:

/// <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); 

Hay un WMI versión disponible también (para probando máquinas remotas).

+0

Este es un ganador. – tofutim

+1

Tenga en cuenta que este código está licenciado bajo la [Licencia pública de Microsoft] (http://www.opensource.org/licenses/MS-PL). – ladenedge

+0

versión WMI sin .net administrado? Me gustaría ver que, no lo he encontrado hasta ahora – JohnZaj

-2

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 ...

+5

Asegúrese de recuperar el nombre correcto del directorio localizado de la API de Win32 en lugar de codificarlo. –

+0

Diría que es una buena idea, pero no se puede asumir que un usuario nunca haría esto por algún motivo oscuro. – dotnetdev

+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

-7

utilizar una versión de los siguientes:

public static bool Is64BitSystem() 
    { 
     if (Directory.Exists(Environment.GetEnvironmentVariable("Program Files (x86)"))) return true; 
     else return false; 
    } 
+6

Esto no funciona en versiones de XP que no sean en inglés debido al nombre de Carpetas de programa localizado. –

+0

Pero incluso los sistemas de 64 bits tienen esta carpeta jaja – carefulnow1

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 una fácil reutilización del código.

Algunos uso posible es la siguiente:

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); 
} 
+0

El enlace CodePlex parece estar roto. –

4

tengo que hacer esto, pero también tienen que ser capaces como administrador hacerlo de forma remota, cualquiera de los casos 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; 
     } 
    } 
-3

que utilizo:

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

Esto consigue la ruta donde se inició su aplicación en caso de tener que i instalado en varios lugares de la computadora. Además, puedes simplemente hacer la ruta general C:\ ya que el 99.9% de las computadoras tienen instalado Windows en C:\.

+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 llaman "Programa". No estoy seguro, pero XP 64 puede llamarlo "Programa (x86)". – Marc

+1

No lo recomiendo pero podría evitar el problema de localización al expandir el var% ProgramFiles (x86)% –

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); 
    } 
2

Aquí es un (WMI) enfoque Windows Management Instrumentation:

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: 
9

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

En el 99% de los casos, los desarrolladores débil los fondos del administrador del sistema finalmente no se dan cuenta de la potencia que Microsoft siempre ha proporcionado para que cualquiera pueda enumerar Windows.

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

Sin embargo, una cosa a tener en cuenta, la construcción de configuración debe ser Cualquier CPU para esta variable de entorno para devolver 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.

+4

ambiental Su solución devuelve x86 en una MacBook Pro con microprocesador Intel i7-3720QM ejecutando 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 la PC basada en Windows. +1 por intentar. –

+3

stefan Schultze 1: sysadmin 0 ;-) – Beachwalker

+0

No. devolvió "x86" en mi Windows 7 pro, sistema operativo de 64 bits. –

1

Uso esto para conseguir la arquitectura de Windows instalado:

string getOSArchitecture() 
{ 
    string architectureStr; 
    if (Directory.Exists(Environment.GetFolderPath(
          Environment.SpecialFolder.ProgramFilesX86))) { 
     architectureStr ="64-bit"; 
    } 
    else { 
     architectureStr = "32-bit"; 
    } 
    return architectureStr; 
} 
+0

no tengo una propiedad ProgramFilesX86 en w7x64 vs.net 2010 –

79

Si está utilizando .NET Framework 4.0, es fácil:

Environment.Is64BitOperatingSystem 

Ver Environment.Is64BitOperatingSystem Property (MSDN).

+1

¡Definitivamente la mejor respuesta! –

+1

Para geek, implementación interna usando IsWow64Process (...) http://referencesource.microsoft.com/#mscorlib/system/environment.cs,75feca36cdd83149 – Zyo

2

He encontrado que esto es la mejor manera de comprobar si 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 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.

+1

ponga una _ o una letra delante del nombre de la variable si desea para construir en C# (los nombres de las variables no comienzan con los números en C# en la medida en que mi ide me lo dice) – Chris

8

Prueba esto:

Environment.Is64BitOperatingSystem 

Environment.Is64BitProcess 
+5

Gracias por su contribución, 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

+0

Gracias, esta respuesta fue muy simple y me consiguió lo que necesitaba. Veo que fueron rechazados y lo voté porque su respuesta fue la más útil para mí aquí. – MikeMalter

+2

fue downvoted porque es una buena respuesta, pero para un diff. pregunta :) – mikus

-2

Enjoy ;-)

Function Is64Bit() As Boolean 

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

End Function 
+0

-1 ya que esto no funcionará en instalaciones de Windows localizadas. Y usa VB.net mientras que la pregunta está etiquetada para C#. – Marc

11

Desde el blog Chriz Yuen

C# .Net 4.0 introdujo dos nuevos propiedad de entorno Environment.Is64BitOperatingSystem; Environment.Is64BitProcess;

Tenga cuidado cuando utilice estas dos propiedades. prueba en Windows 7 64bits Máquina

//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 
6

Usando dotPeek ayuda a ver cómo el marco de hecho lo hace.Con esto en mente, aquí es lo que he llegado con:

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(); 
1

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

Uso es así:

string Architecture = "This is a " + GetBit() + "bit machine"; 
2

utilicé th es comprobar con éxito en muchos sistemas operativos:

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

Esta carpeta siempre se denomina "SysWOW64", independientemente del idioma del sistema operativo. Esto funciona para .NET Framework 1.1 o superior.

0

Dado que la respuesta aceptada es muy compleja. Hay formas más simples. El mío es una variación del anaswer 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, usando variables de entorno (para compensar las diferentes localizaciones)

p.

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 basada en la versión del sistema operativo.

+1

La respuesta aceptada fue para .NET 2.0. Si tiene .NET 4.0 o posterior, simplemente use Environment.Is64BitOperatingSystem como puede encontrar en la respuesta con la mayoría de los votos. – Marc

+0

Sí, el mío también es para .net 2.0. –

Cuestiones relacionadas