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.


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

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

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


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

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

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

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;

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\";

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.