Cómo determinar mediante programación si un proceso en particular es de 32 bits o de 64 bits

102

¿Cómo puede mi aplicación C # verificar si una aplicación / proceso en particular (nota: no el proceso actual) se está ejecutando en modo de 32 bits o 64 bits?

Por ejemplo, es posible que desee consultar un proceso en particular por su nombre, es decir, 'abc.exe', o según el número de identificación del proceso.

satya
fuente
Por favor, ponga siempre el idioma como una etiqueta; Cambiaré eso ahora en esta publicación. :-)
Dean J
3
Aclare si desea saber que el proceso actual es de 64 bits o si está consultando otro proceso.
Mehrdad Afshari
Duplicado: stackoverflow.com/questions/266082/…
Lawrence Johnston

Respuestas:

177

Una de las formas más interesantes que he visto es esta:

if (IntPtr.Size == 4)
{
    // 32-bit
}
else if (IntPtr.Size == 8)
{
    // 64-bit
}
else
{
    // The future is now!
}

Para saber si OTROS procesos se están ejecutando en el emulador de 64 bits (WOW64), use este código:

namespace Is64Bit
{
    using System;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Runtime.InteropServices;

    internal static class Program
    {
        private static void Main()
        {
            foreach (var p in Process.GetProcesses())
            {
                try
                {
                    Console.WriteLine(p.ProcessName + " is " + (p.IsWin64Emulator() ? string.Empty : "not ") + "32-bit");
                }
                catch (Win32Exception ex)
                {
                    if (ex.NativeErrorCode != 0x00000005)
                    {
                        throw;
                    }
                }
            }

            Console.ReadLine();
        }

        private static bool IsWin64Emulator(this Process process)
        {
            if ((Environment.OSVersion.Version.Major > 5)
                || ((Environment.OSVersion.Version.Major == 5) && (Environment.OSVersion.Version.Minor >= 1)))
            {
                bool retVal;

                return NativeMethods.IsWow64Process(process.Handle, out retVal) && retVal;
            }

            return false; // not on 64-bit Windows Emulator
        }
    }

    internal static class NativeMethods
    {
        [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool IsWow64Process([In] IntPtr process, [Out] out bool wow64Process);
    }
}
Jesse C. Rebanadora
fuente
8
(Environment.OSVersion.Version.Major >= 5 && Environment.OSVersion.Version.Minor >= 1) Y es por eso que Microsoft tiene que crear calzas de compatibilidad de versiones para evitar errores en un código como ese. ¿Qué sucede cuando sale Windows Vista (6.0)? Y la gente luego habla mal de Microsoft por hacer Windows 7 versión 6.1 en lugar de 7.0, corrige tantos errores de compatibilidad de aplicaciones.
Ian Boyd
4
El nombre de la función IsWin64 es un poco engañoso, creo. Devuelve verdadero si el proceso de 32 bits se ejecuta en el sistema operativo x64.
Denis The Menace
2
¿Por qué usar en processHandle = Process.GetProcessById(process.Id).Handle;lugar de solo processHandle = process.Handle;?
Jonathon Reinhart
1
@JonathonReinhart bueno, ¿no es solo una buena pregunta? No tengo idea. Debe haber sido vestigio de un cambio de hacer las cosas de una manera a otra. ¡Gracias por encontrar eso!
Jesse C. Slicer
1
Esta respuesta es simplemente incorrecta; y devolver false en lugar de generar una excepción en caso de error es un diseño muy malo.
user626528
141

Si está utilizando .Net 4.0, es una sola línea para el proceso actual:

Environment.Is64BitProcess

Consulte Environment.Is64BitProcessProperty (MSDN).

Sam
fuente
2
¿Podrías publicar el código de Is64BitProcess? Quizás pueda usar lo que hace para averiguar si me estoy ejecutando como un proceso de 64 bits.
Ian Boyd
1
@Ian, dudo que Sam esté legalmente autorizado a publicar código MS en este foro. No estoy seguro del contenido exacto de su licencia de referencia, pero estoy bastante seguro de que prohíbe la reproducción del código en cualquier lugar.
ProfK
3
@Ian alguien ha hecho ese trabajo por usted: stackoverflow.com/questions/336633/…
Robert MacLean
4
El OP pidió específicamente consultar otro proceso, no el proceso actual.
Harry Johnston
1
Tenga en cuenta que Microsoft hizo publicar el código para Is64BitProcess( referencesource.microsoft.com/#mscorlib/system/environment.cs ). Sin embargo, es solo una declaración de retorno codificada, controlada por el símbolo de compilación.
Brian
20

La respuesta seleccionada es incorrecta ya que no hace lo que se le preguntó. Comprueba si un proceso es un proceso x86 que se ejecuta en el sistema operativo x64; por lo que devolverá "falso" para un proceso x64 en x64 OS o un proceso x86 que se ejecuta en x86 OS.
Además, no maneja los errores correctamente.

Aquí hay un método más correcto:

internal static class NativeMethods
{
    // see https://msdn.microsoft.com/en-us/library/windows/desktop/ms684139%28v=vs.85%29.aspx
    public static bool Is64Bit(Process process)
    {
        if (!Environment.Is64BitOperatingSystem)
            return false;
        // if this method is not available in your version of .NET, use GetNativeSystemInfo via P/Invoke instead

        bool isWow64;
        if (!IsWow64Process(process.Handle, out isWow64))
            throw new Win32Exception();
        return !isWow64;
    }

    [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool IsWow64Process([In] IntPtr process, [Out] out bool wow64Process);
}
usuario626528
fuente
1
Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE") == "x86"siempre devolverá verdadero para un proceso de 32 bits. Es mejor usarlo System.Environment.Is64BitOperatingSystemsi se admite
.NET4
10

Puede verificar el tamaño de un puntero para determinar si es de 32 bits o de 64 bits.

int bits = IntPtr.Size * 8;
Console.WriteLine( "{0}-bit", bits );
Console.ReadLine();
Darwyn
fuente
6
En el momento en que se publicó esta respuesta por primera vez, no estaba muy claro, pero el OP quería saber cómo consultar otro proceso en lugar del proceso actual.
Harry Johnston
3
[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;
}
Praveen MB
fuente
5
El OP preguntó específicamente cómo consultar otro proceso, no el proceso actual.
Harry Johnston
1

Aquí está la verificación de una línea.

bool is64Bit = IntPtr.Size == 8;
Vikram Bose
fuente
6
El OP preguntó específicamente cómo consultar otro proceso, no el proceso actual.
Harry Johnston
0

Me gusta usar esto:

string e = Environment.Is64BitOperatingSystem

De esta manera, si necesito ubicar o verificar un archivo, puedo escribir fácilmente:

string e = Environment.Is64BitOperatingSystem

       // If 64 bit locate the 32 bit folder
       ? @"C:\Program Files (x86)\"

       // Else 32 bit
       : @"C:\Program Files\";
usuario1351333
fuente
13
¿Qué pasa con el proceso de 32 bits en la máquina con sistema operativo de 64 bits?
Kiquenet
3
¿Es realmente tan difícil de usar en Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)lugar de codificar `C: \ Archivos de programa`?
Luaan
2
Nunca codifique "archivos de programa", porque es una cadena localizable. Αρχεία Εφαρμογών, Arquivos de Programas, etc.
stevieg