Como determinar programaticamente se um determinado processo é de 32 ou 64 bits

102

Como meu aplicativo C # pode verificar se um determinado aplicativo / processo (observação: não o processo atual) está sendo executado no modo de 32 ou 64 bits?

Por exemplo, posso querer consultar um processo específico por nome, ou seja, 'abc.exe', ou com base no número de identificação do processo.

satya
fonte
Sempre coloque o idioma como uma tag; Vou mudar isso agora neste post. :-)
Dean J
3
Esclareça se deseja saber se o processo atual é de 64 bits ou se deseja consultar outro processo.
Mehrdad Afshari
Dupelicate: stackoverflow.com/questions/266082/…
Lawrence Johnston

Respostas:

177

Uma das maneiras mais interessantes que vi é esta:

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

Para descobrir se OUTROS processos estão sendo executados no 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. Slicer
fonte
8
(Environment.OSVersion.Version.Major >= 5 && Environment.OSVersion.Version.Minor >= 1) E é por isso que a Microsoft precisa criar shims de compatibilidade de mentira de versão - para contornar bugs em códigos como esse. O que acontecerá quando o Windows Vista (6.0) for lançado? E as pessoas criticam a Microsoft por fazer o Windows 7 versão 6.1 em vez da 7.0, que corrige muitos bugs de compatibilidade de aplicativos.
Ian Boyd,
4
O nome da função IsWin64 é um pouco enganador, eu acho. Ele retorna verdadeiro se o processo de 32 bits estiver sendo executado no sistema operacional x64.
Denis The Menace,
2
Por que usar em processHandle = Process.GetProcessById(process.Id).Handle;vez de apenas processHandle = process.Handle;?
Jonathon Reinhart de
1
@JonathonReinhart bem, essa não é apenas uma boa pergunta. Eu não faço ideia. Deve ter sido um vestígio de uma mudança de fazer as coisas de uma maneira para outra. Obrigado por encontrar isso!
Jesse C. Slicer
1
Esta resposta está simplesmente incorreta; e retornar false em vez de levantar uma exceção em caso de erro é um projeto muito ruim.
user626528
141

Se você estiver usando .Net 4.0, é uma linha única para o processo atual:

Environment.Is64BitProcess

Consulte Environment.Is64BitProcessProperty (MSDN).

Sam
fonte
2
Você poderia postar o código de Is64BitProcess? Talvez eu possa usar o que faz para descobrir se estou executando como um processo de 64 bits.
Ian Boyd,
1
@Ian, duvido que Sam tenha permissão legal para postar código MS neste fórum. Não tenho certeza do conteúdo exato de sua licença de referência, mas tenho quase certeza de que ela proíbe a reprodução do código em qualquer lugar.
ProfK de
3
@Ian alguém fez esse trabalho para você: stackoverflow.com/questions/336633/…
Robert MacLean
4
O OP pediu especificamente para consultar outro processo, não o processo atual.
Harry Johnston
1
Note-se que a Microsoft fez postar o código para Is64BitProcess( referencesource.microsoft.com/#mscorlib/system/environment.cs ). No entanto, é apenas uma instrução de retorno embutida no código, controlada pelo símbolo de compilação.
Brian,
20

A resposta selecionada está incorreta porque não cumpre o que foi pedido. Ele verifica se um processo é um processo x86 em execução no sistema operacional x64; portanto, ele retornará "false" para um processo x64 no sistema operacional x64 ou processo x86 em execução no sistema operacional x86.
Além disso, ele não trata os erros corretamente.

Aqui está um método mais correto:

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);
}
user626528
fonte
1
Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE") == "x86"sempre retornará verdadeiro para um processo de 32 bits. Melhor usar System.Environment.Is64BitOperatingSystemse o .NET4 for compatível
Aizzat Suhardi,
10

Você pode verificar o tamanho de um ponteiro para determinar se ele é de 32 bits ou 64 bits.

int bits = IntPtr.Size * 8;
Console.WriteLine( "{0}-bit", bits );
Console.ReadLine();
Darwyn
fonte
6
No momento em que esta resposta foi postada pela primeira vez, não estava muito clara, mas o OP queria saber como consultar outro processo em vez do processo atual.
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
fonte
5
O OP perguntou especificamente como consultar outro processo, não o processo atual.
Harry Johnston
1

Aqui está a verificação de uma linha.

bool is64Bit = IntPtr.Size == 8;
Vikram Bose
fonte
6
O OP perguntou especificamente como consultar outro processo, não o processo atual.
Harry Johnston
0

Eu gosto de usar isto:

string e = Environment.Is64BitOperatingSystem

Desta forma, se eu precisar localizar ou verificar um arquivo, posso escrever facilmente:

string e = Environment.Is64BitOperatingSystem

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

       // Else 32 bit
       : @"C:\Program Files\";
usuário1351333
fonte
13
que tal o processo de 32 bits na máquina de SO de 64 bits?
Kiquenet
3
É realmente tão difícil usar em Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)vez de embutir em código `C: \ Arquivos de programas`?
Luaan
2
Nunca codifique "arquivos de programa", porque é uma string localizável. Αρχεία Εφαρμογών, Arquivos de Programas, etc.
stevieg