Como detectar a plataforma Windows de 64 bits com o .NET?

269

Em um aplicativo .NET 2.0 C #, uso o seguinte código para detectar a plataforma do sistema operacional:

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

Isso retorna "Win32NT". O problema é que ele retorna "Win32NT" mesmo quando executado no Windows Vista de 64 bits.

Existe algum outro método para conhecer a plataforma correta (32 ou 64 bits)?

Observe que ele também deve detectar 64 bits quando executado como um aplicativo de 32 bits no Windows 64 bits.

Marc
fonte

Respostas:

200

IntPtr.Size não retornará o valor correto se estiver executando no .NET Framework 2.0 de 32 bits no Windows de 64 bits (retornaria 32 bits).

Como descreve Raymond Chen, da Microsoft, você deve primeiro verificar se está executando um processo de 64 bits (acho que no .NET você pode fazer isso verificando IntPtr.Size) e, se estiver executando um processo de 32 bits, ainda assim precisa chamar a função API do Windows, IsWow64Process. Se isso retornar verdadeiro, você estará executando um processo de 32 bits no Windows de 64 bits.

Raymond Chen, da Microsoft: Como detectar programaticamente se você está executando no Windows de 64 bits

Minha solução:

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
fonte
7
Ao executar em um sistema operacional de 32 bits, qualquer chamada para IsWow64Process lançará uma exceção, pois essa entrada está ausente no kernel32.dll. Você deve verificar a solução mostrada no codeplex em 1code.codeplex.com/SourceControl/changeset/view/39074#842775 . Também tenho uma solução baseada no código listado na parte inferior desta página, que usa métodos de extensão, se você se preocupa com reutilizando o código.
dmihailescu 02/02
7
O IsWow64Process foi introduzido com o Win XP SP2. Esse código funciona bem se você precisar do XP SP2 ou de uma versão mais recente.
Marc
3
@dmihailescu, você pode simplesmente usar DoesWin32MethodExist antes de chamar IsWow64Process, que é o que faz a implementação .net 4.0 do is64BitOperatingSystem .net 4.0.
noobish
4
Sua solução retorna o valor correto em um MacBook Pro com o microprocessador Intel i7-3720QM executando o Bootcamp usando uma partição Widows 7 Ultimate. +1
Mark Kram
11
FYI: começando com .Net 4.0, você pode apenas verificar System.Environment.Is64BitOperatingSystem. Você pode editar isso em sua resposta ou me dar permissão para editá-lo em sua resposta?
Joel Coehoorn
242

O .NET 4 possui duas novas propriedades na classe Environment, Is64BitProcess e Is64BitOperatingSystem . Curiosamente, se você usa o Reflector, pode ver que eles são implementados de maneira diferente nas versões de 32 e 64 bits do mscorlib. A versão de 32 bits retorna false para Is64BitProcess e chama IsWow64Process via P / Invoke para Is64BitOperatingSystem. A versão de 64 bits apenas retorna true para ambos.

Phil Devaney
fonte
5
Em vez de Refletor, por que não fazer o download da fonte? Então você recebe os comentários e outras "notas".
AMissico
3
De acordo com a fonte de referência, ele é mais ou menos assim: if (IntPtr.Size == 8) return true; if(!DoesWin32MethodExist(...,"IsWow64Process")) return false; return IsWow64Process(GetCurrentProcess());(pseudo-código)
Polinômio
5
Agradável. Se o usuário estiver usando o .NET 4.0, essa é definitivamente a resposta correta (por exemplo, Environment.Is64BitOperatingSystem). - A propriedade FYI não parece existir no .NET 3.5.
BrainSlugs83
4
Isso não responde à pergunta que diz especificamente .Net 2.0 #
abbottdev
O .NET Core foi lançado sob a licença MIT, o que significa que você pode ler o código-fonte para Is64BitProcesse Is64BitOperatingSystem(links para a versão 2.0).
Cristian Ciupitu 16/02
51

Esta é apenas uma implementação do que é sugerido acima por Bruno Lopez, mas funciona no Win2k + todos os service packs do WinXP. Só pensei em postá-lo para que outras pessoas não o rolassem manualmente. (teria postado como um comentário, mas sou um novo usuário!)

[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
fonte
49

A resposta completa é esta (retirada das respostas de stefan-mg, ripper234 e 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;
    } 

Primeiro verifique se você está em um processo de 64 bits. Caso contrário, verifique se o processo de 32 bits é um Wow64Process.

Bruno Lopes
fonte
13
Isso falhará no Win2000 e WinXP SP1 e versões anteriores. Você precisa verificar se a função IsWow64Process () existe antes de chamá-la, porque foi introduzida apenas no XP SP2 e Vista / Win7.
user9876
2
@ user9876, alguém ainda tem como alvo esses sistemas antigos?
CMircea
5
Este exemplo falha ao descartar a instância Process retornada por Process.GetCurrentProcess ().
Joe
42

A Microsoft colocou um exemplo de código para isso:

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

Se parece com isso:

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

Também existe uma versão WMI (para testar máquinas remotas).

synhershko
fonte
1
Observe que este código está licenciado sob a Licença Pública da Microsoft .
ladenedge 12/09/11
Versão WMI sem .net gerenciado? Eu gostaria de ver isso, não tê-lo encontrado até agora
JohnZaj
16

Você também pode verificar a PROCESSOR_ARCHITECTUREvariável de ambiente.

Ele não existe ou está definido como "x86" no 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
fonte
1
Só porque você tem um processador de 64 bits não significa que você tem um sistema operacional de 64 bits
David
2
@ David Este relata a arquitetura do processador do Windows; não a CPU. Veja a explicação detalhada a partir de "O Código" nesta página: andrewensley.com/2009/06/c-detect-windows-os-part-1
Andrew Ensley
Apenas para adicionar 2 centavos, quando você executa isso, e seu aplicativo está configurado como prefer 32-bitcom Any CPUo seu Platform Target, você receberá x86, mas se você desmarcá Prefer 32-bit-lo, receberá AMD64.
XAMlMAX
14

Do blog de Chriz Yuen

C # .Net 4.0 Introduziu duas novas propriedades de ambiente Environment.Is64BitOperatingSystem; Environment.Is64BitProcess;

Tenha cuidado ao usar essas duas propriedades. Teste na máquina Windows 7 64bits

//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
fonte
12

Maneira mais rápida:

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

Nota: isso é muito direto e funciona corretamente em 64 bits apenas se o programa não forçar a execução como um processo de 32 bits (por exemplo,<Prefer32Bit>true</Prefer32Bit>nas configurações do projeto).

BobbyShaftoe
fonte
32
Isso não funcionará - se estiver sendo executado no .NET Framework 2.0 de 32 bits no Windows de 64 bits, ele retornará 32 bits.
Stefan Schultze
Certo, eu esqueci essa situação. Eu editei a pergunta para mencionar isso também. Obrigado stefan-mg.
Marc
1
Isso não está correto; a plataforma pode ter 64 bits, mas você ainda está executando no modo de 32 bits.
Sebastian Good
11

Tente o seguinte:

Environment.Is64BitOperatingSystem

Environment.Is64BitProcess
user2235582
fonte
5
Obrigado pela sua contribuição, mas leia as respostas disponíveis antes de postar, pois essa solução já foi fornecida. Observe também que a pergunta original sobre .net 2, que não tem essas duas propriedades que foram introduzidos apenas com .net 4.
Marc
9

@foobar: Você está certo, é muito fácil;)

Em 99% dos casos, os desenvolvedores com histórico de administrador de sistema fraco acabam não percebendo o poder que a Microsoft sempre forneceu para qualquer pessoa enumerar o Windows.

Os administradores de sistema sempre escrevem códigos melhores e mais simples quando se trata de tal ponto.

No entanto, uma coisa a ser observada, a configuração da compilação deve ser AnyCPU para essa variável de ambiente para retornar os valores corretos nos sistemas corretos:

System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")

Isso retornará "X86" no Windows de 32 bits e "AMD64" no Windows de 64 bits.

SomeSysadmin
fonte
4
Sua solução retorna x86 em um MacBook Pro com microprocessador Intel i7-3720QM executando o Bootcamp com uma partição Widows 7 Ultimate. A solução de Stefan Schultze identificou corretamente o processador como um 64 bits. Tenho certeza de que sua solução funciona em 99% do PC baseado no Windows. +1 por tentar.
Mark Kram
Não. retornou "x86" no meu sistema operacional Windows 7 Pro de 64 bits.
precisa
7

O uso do dotPeek ajuda a ver como a estrutura realmente faz isso. Com isso em mente, aqui está o que eu criei:

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

Exemplo de uso:

EnvironmentHelper.Is64BitOperatingSystem();
Alexandru
fonte
6

Use estas duas variáveis ​​de ambiente (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 a publicação no blog HOWTO: Detectar Process Bitness .

Santhosh
fonte
Você viu a parte em que a pergunta era sobre .NET e não C / C ++? E que este é um tempo de compilação versus uma verificação de tempo de execução. Além disso, o código está executando tarefas e não comparações.
Dvallejo 11/01
Este código funciona no .NET (testado no 2.0). As variáveis ​​Env podem ser acessadas por: Environment.GetEnvironmentVariable ("PROCESSOR_ARCHITECTURE"); Environment.GetEnvironmentVariable ("PROCESSOR_ARCHITEW6432");
precisa saber é o seguinte
5

Eu usei essa verificação com êxito em muitos sistemas operacionais:

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

Essa pasta sempre é chamada "SysWOW64", independentemente do idioma do sistema operacional. Isso funciona para o .NET Framework 1.1 ou superior.

Alexandru Dicu
fonte
E o que me impede como usuário com direitos administrativos de criar uma pasta chamada SysWOW64em um %windir%sistema operacional de 32 bits? A presença de uma pasta significa exatamente isso: que a pasta está presente.
cogumel0
Quais são as chances de um usuário criar essa pasta de propósito? Essa é apenas uma maneira diferente de verificar se o sistema operacional é x64.
Alexandru Dicu
Quais são as chances do seu computador receber um vírus? Como as chances são muito baixas, é melhor não instalar nenhuma proteção, então ... Programar não significa criar algo que tenha poucas chances de falha consciente . Trata-se de criar algo que tem poucas chances de falhar sem saber - e depois consertá-lo. O primeiro é chamado de programação ruim / implementação ruim, o segundo é chamado de bug.
cogumel0
@AlexandruDicu Você deve mencionar na resposta que essa abordagem não é 100% precisa e ainda corre o risco de gerar uma saída errada, caso a pasta seja criada propositadamente por qualquer aplicativo ou usuário de terceiros manualmente.
Rajesh Mishra
4

Preciso fazer isso, mas também preciso ser administrador, remotamente, caso isso pareça funcionar muito bem para mim:

    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
fonte
4

Esta é uma solução baseada no código da Microsoft em http://1code.codeplex.com/SourceControl/changeset/view/39074#842775 . Ele usa métodos de extensão para facilitar a reutilização de código.

Alguns usos possíveis são mostrados abaixo:

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
fonte
O link do CodePlex parece estar quebrado.
22613 Peter Mortensen
3

Aqui está a abordagem direta em C # usando DllImport nesta 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
fonte
Você ainda precisa verificar o tamanho do ponteiro primeiro, caso contrário ele apenas verifica se é um processo de 32 bits em um sistema de 64 bits
Bruno Lopes
1
Também trava em um sistema operacional mais antigo, pois IsWow64Processnão existe.
Polynomial
3

Estou usando o código a seguir. Nota: Foi feito para um projeto 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
fonte
2

Eu achei que essa era a melhor maneira de verificar a plataforma do sistema e o processo:

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

A primeira propriedade retorna true para o sistema de 64 bits e false para 32 bits. A segunda propriedade retorna true para o processo de 64 bits e false para 32 bits.

A necessidade dessas duas propriedades é porque você pode executar processos de 32 bits no sistema de 64 bits, portanto, será necessário verificar o sistema e o processo.

OmarElsherif
fonte
1
colocar uma _ ou uma letra na frente do nome da variável, se você quiser construir em c # (nomes de variáveis não começar com números em c #, tanto quanto a minha ide está me dizendo!)
Chris
2

Tudo bem, mas isso também deve funcionar em env:

PROCESSOR_ARCHITECTURE=x86

..

PROCESSOR_ARCHITECTURE=AMD64

Muito fácil, talvez ;-)

Peter Mortensen
fonte
2

Aqui está uma abordagem da WMI ( Instrumentação de Gerenciamento do Windows ):

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:
user1054695
fonte
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
fonte
3
Isso é legal, mas essa classe é do namespace Microsoft.UpdateServices.Administration, que é o Microsoft WSUS. Não gosto de incluir essa referência apenas para conhecer os bits da plataforma.
Marc
"C: \ Program Files \ Microsoft.NET \ SDK \ v2.0 64 bits \ LateBreaking \ PlatformInvoke \ WinAPIs \ OSINFO \ CS \ OSInfoCS.sln"
AMissico
1

Inclua o seguinte código em uma classe em seu projeto:

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

Use-o assim:

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

Use isto para obter a arquitetura instalada do Windows:

string getOSArchitecture()
{
    string architectureStr;
    if (Directory.Exists(Environment.GetFolderPath(
                           Environment.SpecialFolder.ProgramFilesX86))) {
        architectureStr ="64-bit";
    }
    else {
        architectureStr = "32-bit";
    }
    return architectureStr;
}
user885959
fonte
eu não tenho uma propriedade ProgramFilesX86 em w7x64 vs.net 2010
Christian Casutt
0

Dado que a resposta aceita é muito complexa. Existem maneiras mais simples. O meu é uma variação do respondente de alexandrudicu. Como as janelas de 64 bits instalam aplicativos de 32 bits nos Arquivos de Programas (x86), é possível verificar se essa pasta existe, usando variáveis ​​de ambiente (para compensar diferentes localizações)

por exemplo

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

Isso para mim é mais rápido e mais simples. Como também desejo acessar um caminho específico nessa pasta com base na versão do sistema operacional.

John Demetriou
fonte
2
A resposta aceita foi para o .NET 2.0. Se você usa o .NET 4.0 ou mais recente, use Environment.Is64BitOperatingSystem, como você pode encontrar na resposta com a maioria dos votos.
Marc
Sim, o meu também é para .net 2.0.
John Demetriou
-2

Aproveitar ;-)

Function Is64Bit() As Boolean

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

End Function
Majid95
fonte
-1, pois isso não funcionará em instalações localizadas do Windows. E ele usa VB.net, enquanto a pergunta está marcada para C #.
Marc
-3

Veja se o "C: \ Arquivos de Programas (x86)" existe. Caso contrário, você estará em um sistema operacional de 32 bits. Nesse caso, o sistema operacional é de 64 bits (Windows Vista ou Windows 7). Parece bastante simples ...

John
fonte
5
Certifique-se de recuperar o nome do diretório localizado correto da API do Win32 em vez de codificá-lo.
Christian Hayter
Eu diria que é uma boa ideia, mas você não pode assumir que um usuário nunca faria isso por algum motivo obscuro.
precisa saber é o seguinte
2
Agora, alguns aplicativos mal escritos estão sendo instalados diretamente em "Arquivos de Programas (x86)" sem levar em consideração a arquitetura. Eu tenho esse diretório na minha máquina de 32 bits graças ao SOAPSonar, por exemplo.
ladenedge
-4

Eu uso:

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

Isso mostra o caminho em que seu aplicativo é iniciado, caso você o tenha instalado em vários locais do computador. Além disso, você pode fazer o C:\caminho geral, já que 99,9% dos computadores por aí têm o Windows instalado C:\.

Ben G
fonte
8
Abordagem muito ruim. E se, no futuro, esse diretório for renomeado? E a versão localizada do Windows? No Windows XP em alemão, "Arquivos de programas" é chamado "Programa". Não tenho certeza, mas o XP 64 pode chamá-lo de "Programa (x86)".
Marc
1
Eu não recomendo isso, mas você pode contornar o problema de localização através da expansão do var ambiental% ProgramFiles (x86)%
Matthew Bloqueio
-7

Eu uso uma versão do seguinte:

    public static bool Is64BitSystem()
    {
        if (Directory.Exists(Environment.GetEnvironmentVariable("Program Files (x86)"))) return true;
        else return false;
    }
Josh
fonte
6
Isso não funciona nas versões XP não em inglês por causa do nome localizado nas Pastas de Programas.
Daniel Schlößer 19/04/12
Mas até mesmo sistemas de 64 bits tem esta pasta haha
carefulnow1