Как определить 64-битную платформу Windows с .NET?

В приложении .СЕТЬ 2.0 C# я использую следующий код для определения платформы операционной системы:

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

Это возвращает Win32NT. Проблема в том, что он возвращает Win32NT даже при работе в 64-битной Windows Vista.

Есть ли другой способ узнать правильную платформу (32  или 64 bit)?

Обратите внимание, что он также должен обнаруживать 64 bit при запуске как 32 bit приложения в Windows 64 bit.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
278
0
205 167
30
Перейти к ответу Данный вопрос помечен как решенный

Ответы 30

Самый быстрый способ:

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

Примечание: - это очень прямой метод и работает правильно в 64-битном режиме, только если программа не выполняет принудительное выполнение как 32-битный процесс (например, через <Prefer32Bit>true</Prefer32Bit> в настройках проекта).

Это не сработает - если вы работаете в 32-битной .NET Framework 2.0 в 64-битной Windows, она вернет 32-битную версию.

Stefan Schultze 03.12.2008 13:11

Правильно, я забыл об этой ситуации. Я отредактировал вопрос, чтобы также упомянуть об этом. Спасибо stefan-mg.

Marc 03.12.2008 13:18

Это неверно; платформа может быть 64-битной, но вы по-прежнему работаете в 32-битном режиме.

Sebastian Good 10.08.2011 23:30
Ответ принят как подходящий

Обновлено: Как предлагают Джоэл Кохорн и другие, начиная с .NET Framework 4.0, вы можете просто проверить Environment.Is64BitOperatingSystem.


IntPtr.Size не вернет правильное значение при работе в 32-битной .NET Framework 2.0 в 64-битной Windows (вернет 32-битную).

Как описывает Раймонд Чен из Microsoft, вы должны сначала проверить, работает ли он в 64-битном процессе (я думаю, что в .NET вы можете сделать это, проверив IntPtr.Size), и если вы работаете в 32-битном процессе, вы все равно необходимо вызвать функцию Win API IsWow64Process. Если это вернет истину, вы работаете в 32-битном процессе в 64-битной Windows.

Раймонд Чен из Microsoft: Как программно определить, работаете ли вы в 64-битной Windows

Мое решение:

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

При работе в 32-битной ОС любой вызов IsWow64Process вызовет исключение, поскольку эта запись отсутствует в kernel32.dll. Вы должны проверить решение, показанное из codeplex в 1code.codeplex.com/SourceControl/changeset/view/39074#842775. У меня также есть решение, основанное на этом коде, указанном внизу этой страницы, которое использует методы расширения, если вы хотите повторно использовать код.

dmihailescu 02.02.2011 21:29

IsWow64Process был представлен в Win XP SP2. Этот код отлично работает, если вам требуется XP SP2 или любая более новая версия.

Marc 04.02.2011 12:12

@dmihailescu, вы можете просто использовать DoesWin32MethodExist перед вызовом IsWow64Process, что и делает реализация is64BitOperatingSystem .net 4.0.

noobish 19.03.2011 02:04

Ваше решение возвращает правильное значение на MacBook Pro с микропроцессором Intel i7-3720QM, на котором запущен Bootcamp с разделом Widows 7 Ultimate. +1

Mark Kram 15.07.2012 04:40

отличный код, спасибо! Возможно, вы захотите добавить static в свойствах :) в противном случае у меня все работало нормально, протестировано 32 бит, 32 на 64 и чистый 64 бит.

Damian Vogel 22.08.2012 17:10

@dmihailescu: «К сожалению, это решение ошибочно». Что ж, это полезно. Как это ущербно?

T.J. Crowder 24.06.2013 13:17

@ T.J. Crowder dmihailescu ответил на это во втором комментарии и последующем ответе на вопрос OP. Я не говорю, что он прав или нет - просто говорю, что он ответил на это. Однако «К сожалению, это решение некорректно» - довольно ужасный комментарий.

basher 29.08.2013 17:40

К вашему сведению: начиная с .Net 4.0 вы можете просто проверить System.Environment.Is64BitOperatingSystem. Можете ли вы отредактировать это в своем ответе или разрешить мне изменить это в свой ответ?

Joel Coehoorn 21.11.2013 19:01

Вот прямой подход в C# с использованием DllImport из эта страница.

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

Вам все равно нужно сначала проверить размер указателя, иначе он просто проверяет, является ли это 32-битный процесс в 64-битной системе.

Bruno Lopes 25.03.2009 15:41

Также дает сбой в более старой ОС, поскольку IsWow64Process не существует.

Polynomial 20.01.2012 02:37

Полный ответ таков (взят из ответов stefan-mg, ripper234 и 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;
    } 

Сначала проверьте, используете ли вы 64-битный процесс. Если нет, проверьте, является ли 32-битный процесс Wow64Process.

Это не сработает под Win2000 и WinXP SP1 и ранее. Вам необходимо проверить, существует ли функция IsWow64Process (), прежде чем вызывать ее, потому что она была представлена ​​только в XP SP2 и Vista / Win7.

user9876 16.11.2009 15:19

@ user9876, кто-нибудь все еще нацелен на эти старинные системы?

CMircea 27.04.2011 00:58

В этом примере не удается удалить экземпляр Process, возвращенный Process.GetCurrentProcess ().

Joe 09.09.2011 22:20

Вы также можете проверить переменную среды PROCESSOR_ARCHITECTURE.

Он либо не существует, либо установлен на «x86» в 32-битной Windows.

private int GetOSArchitecture()
{
    string pa = 
        Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE");
    return ((String.IsNullOrEmpty(pa) || 
             String.Compare(pa, 0, "x86", 0, 3, true) == 0) ? 32 : 64);
}

Тот факт, что у вас 64-битный процессор, не означает, что у вас 64-битная ОС.

David 09.05.2013 11:22

@David Сообщает об архитектуре процессора Windows; не процессор. См. Подробное объяснение, начиная с «Кодекса» на этой странице: andrewensley.com/2009/06/c-detect-windows-os-part-1

Andrew Ensley 10.05.2013 01:02

Просто добавьте 2 цента, когда вы запустите это, и ваше приложение настроено на prefer 32-bit с Any CPU в качестве вашего Platform Target, вы получите x86, но если вы снимете галочку с Prefer 32-bit, вы получите AMD64.

XAMlMAX 10.08.2018 15:32

Все в порядке, но это также должно работать с env:

PROCESSOR_ARCHITECTURE=x86

..

PROCESSOR_ARCHITECTURE=AMD64

Возможно, слишком просто ;-)

Это просто реализация того, что было предложено выше Бруно Лопесом, но оно работает на Win2k + все пакеты обновлений WinXP. Просто подумал, что выложу его, чтобы другие люди не скручивали его вручную. (написал бы как комментарий, но я новый пользователь!)

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

.NET 4 имеет два новых свойства в классе Environment: Is64BitProcess и Is64BitOperatingSystem. Интересно, что если вы используете Reflector, вы можете увидеть, что они по-разному реализованы в 32-битной и 64-битной версиях mscorlib. 32-разрядная версия возвращает false для Is64BitProcess и вызывает IsWow64Process через P / Invoke для Is64BitOperatingSystem. 64-битная версия просто возвращает истину для обоих.

Вместо Reflector почему бы просто не скачать исходный код. Затем вы получите комментарии и другие «заметки».

AMissico 25.07.2011 20:39

Согласно справочному источнику, он делает что-то вроде этого: if (IntPtr.Size == 8) return true; if (!DoesWin32MethodExist(...,"IsWow64Process")) return false; return IsWow64Process(GetCurrentProcess()); (псевдокод)

Polynomial 20.01.2012 02:33

Хороший. Если пользователь использует .NET 4.0, это определенно правильный ответ (например, Environment.Is64BitOperatingSystem). - Свойство FYI, похоже, отсутствует в .NET 3.5.

BrainSlugs83 30.05.2013 04:49

Это не отвечает на вопрос, в котором конкретно говорится о .Net 2.0.

abbottdev 24.07.2015 11:43

.NET Core выпущен под лицензией MIT, что означает, что вы можете читать исходный код для Is64BitProcess и Is64BitOperatingSystem (ссылки для версии 2.0).

Cristian Ciupitu 16.02.2018 09:09

Используйте эти две переменные среды (псевдокод):

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
        }

См. Сообщение в блоге HOWTO: определение разрядности процесса.

Вы видели ту часть, где вопрос касался .NET, а не C / C++? И что это время компиляции, а не проверка во время выполнения. Кроме того, код выполняет присваивание, а не сравнения.

dvallejo 12.01.2013 02:22

Этот код работает на .NET (проверено на 2.0). Доступ к переменным Env можно получить с помощью: Environment.GetEnvironmentVariable ("PROCESSOR_ARCHITECTURE") ‌; Environment.GetEnvironmentVariable ("PROCESSOR_ARCHITEW6432") ‌;

andrew.fox 07.06.2013 13:10

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

Это все хорошо, но этот класс принадлежит пространству имен Microsoft.UpdateServices.Administration, которое является Microsoft WSUS. Я не люблю включать эту ссылку только для того, чтобы узнать детали платформы.

Marc 22.04.2010 18:10

"C: \ Program Files \ Microsoft.NET \ SDK \ v2.0 64bit \ LateBreaking \ PlatformInvoke \ WinAPIs \ OSInfo \ CS \ OSInfoCS‌ .sln"

AMissico 25.07.2011 21:09

Microsoft предоставила для этого образец кода:

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

Выглядит это так:

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

Также доступна версия WMI (для тестирования удаленных машин).

Обратите внимание, что этот код находится под лицензией Общественная лицензия Microsoft.

ladenedge 12.09.2011 20:28

Версия WMI без управляемого .net? Я бы хотел это увидеть, пока не нашел

JohnZaj 28.01.2012 10:19

Просто посмотрите, существует ли «C: \ Program Files (x86)». Если нет, то вы используете 32-битную ОС. Если это так, то ОС 64-разрядная (Windows Vista или Windows 7). Вроде достаточно просто ...

Убедитесь, что вы получили правильное локализованное имя каталога из Win32 API, а не жестко его закодировали.

Christian Hayter 17.09.2010 12:42

Я бы сказал, что это хорошая идея, но вы не можете предположить, что пользователь никогда не сделает этого по какой-то непонятной причине.

GurdeepS 03.04.2011 02:27

Некоторые плохо написанные приложения теперь устанавливаются непосредственно в «Program Files (x86)» безотносительно к архитектуре. У меня есть этот каталог на моей 32-битной машине, например, благодаря SOAPSonar.

ladenedge 12.09.2011 20:18

Я использую следующую версию:

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

Это не работает в версиях XP, отличных от английского, из-за локализованного имени программных папок.

Daniel Schlößer 19.04.2012 13:45

Но даже в 64-битных системах эта папка есть хаха

carefulnow1 07.08.2016 06:23

Это решение, основанное на коде Microsoft по адресу http://1code.codeplex.com/SourceControl/changeset/view/39074#842775. Он использует методы расширения для простого повторного использования кода.

Некоторые возможные варианты использования показаны ниже:

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

Ссылка CodePlex кажется неработающей.

Peter Mortensen 21.03.2013 23:37

Мне нужно сделать это, но я также должен иметь возможность как администратор делать это удаленно, в любом случае это, похоже, работает для меня довольно хорошо:

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

Я использую:

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

Это получает путь, по которому ваше приложение запускается, если оно установлено в разных местах на компьютере. Кроме того, вы можете просто использовать общий путь C:\, поскольку на 99,9% компьютеров Windows установлена ​​на C:\.

Очень плохой подход. Что, если в будущем этот каталог будет переименован? А как насчет локализованной версии Windows? В Windows XP немецкие «Program Files» называются «Program». Я не уверен, но XP 64 может, таким образом, называть это «Программа (x86)».

Marc 14.11.2011 16:16

Я не рекомендую это делать, но вы можете обойти проблему локализации, расширив окружение var% ProgramFiles (x86)%

Matthew Lock 02.04.2012 11:58

Я использую следующий код. Примечание: это сделано для проекта 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);
    }

Вот подход Инструментарий управления Windows (WMI):

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:

@foobar: Вы правы, это слишком просто;)

В 99% случаев разработчики со слабым опытом системного администратора в конечном итоге не осознают возможности, которые Microsoft всегда предоставляла любому для перечисления Windows.

Системные администраторы всегда будут писать лучший и более простой код, когда доходит до такой точки.

Тем не менее, следует отметить, что конфигурация сборки должна быть AnyCPU, чтобы эта переменная среды возвращала правильные значения в правильных системах:

System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")

Это вернет «X86» в 32-битной Windows и «AMD64» в 64-битной Windows.

Ваше решение возвращает x86 на MacBook Pro с микропроцессором Intel i7-3720QM, на котором запущен Bootcamp с разделом Widows 7 Ultimate. Решение Стефана Шульце правильно идентифицировало процессор как 64-битный. Я уверен, что ваше решение работает на 99% компьютеров под управлением Windows. +1 за попытку.

Mark Kram 15.07.2012 04:39

Неа. вернул "x86" в моей 64-разрядной операционной системе Windows 7 Pro.

Hagai L 24.12.2012 17:55

Используйте это, чтобы получить установленную архитектуру Windows:

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

у меня нет свойства ProgramFilesX86 на w7x64 vs.net 2010

Christian Casutt 15.08.2013 14:14

Если вы используете .NET Framework 4.0, это просто:

Environment.Is64BitOperatingSystem

См. Environment.Is64BitOperatingSystem Свойство (MSDN).

Для компьютерщиков внутренняя реализация с использованием IsWow64Process (...) linksource.microsoft.com/#mscorlib/system/…

Zyo 29.11.2015 07:04

Я обнаружил, что это лучший способ проверить платформу системы и процесс:

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

Первое свойство возвращает true для 64-битной системы и false для 32-битной. Второе свойство возвращает true для 64-битного процесса и false для 32-битного.

Эти два свойства необходимы, потому что вы можете запускать 32-битные процессы в 64-битной системе, поэтому вам нужно будет проверить как систему, так и процесс.

поместите _ или букву перед именем переменной, если вы хотите, чтобы она была встроена в C# (имена переменных не начинаются с цифр в C#, насколько мне подсказывает мой ide!)

Chris 05.05.2014 21:27

Попробуй это:

Environment.Is64BitOperatingSystem

Environment.Is64BitProcess

Спасибо за ваш вклад, но, пожалуйста, прочтите доступные ответы перед публикацией, так как это решение уже предоставлено. Также обратите внимание, что исходный вопрос касался .net 2, у которого нет этих двух свойств, которые были введены только с .net 4.

Marc 09.04.2013 10:13

Наслаждаться ;-)

Function Is64Bit() As Boolean

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

End Function

-1, так как это не будет работать с локализованными установками Windows. И он использует VB.net, тогда как вопрос помечен для C#.

Marc 04.12.2013 19:27

Из блога Chriz Yuen

C# .Net 4.0 Введены два новых свойства среды. Environment.Is64BitOperatingSystem; Environment.Is64BitProcess;

Пожалуйста, будьте осторожны при использовании обоих свойств. Тест на машине с 64-битной Windows 7

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

Использование dotPeek помогает увидеть, как на самом деле это работает фреймворк. Имея это в виду, вот что я придумал:

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

Пример использования:

EnvironmentHelper.Is64BitOperatingSystem();

Включите следующий код в класс вашего проекта:

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

Используйте это так:

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

Я успешно использовал эту проверку во многих операционных системах:

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

Эта папка всегда называется «SysWOW64», независимо от языка операционной системы. Это работает для .NET Framework 1.1 или выше.

И что мешает мне как пользователю с правами администратора создать папку SysWOW64 на %windir% в 32-битной ОС? Наличие папки означает именно то, что: что папка присутствует.

cogumel0 13.06.2018 15:15

Каковы шансы, что пользователь создаст такую ​​папку специально? Это просто другой способ проверить, является ли операционная система x64.

Alexandru Dicu 10.07.2018 14:25

Каковы шансы, что ваш компьютер заразится вирусом? Поскольку шансы довольно низкие, лучше не устанавливать никакой защиты ... Программирование не о создании чего-то, что имеет низкие шансы на отказ сознательно. Речь идет о создании чего-то, что имеет низкие шансы на сбой неосознанно, а затем исправить это. Первый называется плохим программированием / плохой реализацией, второй - ошибкой.

cogumel0 23.07.2018 18:47

@AlexandruDicu Вы должны упомянуть в ответе, что этот подход не является точным на 100% и все же существует риск выдачи неправильного вывода в случае, если папка создается намеренно каким-либо сторонним приложением или пользователем вручную.

Rajesh Mishra 15.10.2019 10:22

Учитывая, что принятый ответ очень сложен. Есть способы попроще. Моя - вариант анасвера александрудику. Учитывая, что 64-разрядные окна устанавливают 32-разрядные приложения в Program Files (x86), вы можете проверить, существует ли эта папка, используя переменные среды (для компенсации различных локализаций)

например

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

Это для меня быстрее и проще. Учитывая, что я также хочу получить доступ к определенному пути в этой папке в зависимости от версии ОС.

Принятый ответ был для .NET 2.0. Если вы используете .NET 4.0 или новее, просто используйте Environment.Is64BitOperatingSystem, как вы можете найти в ответе с наибольшим количеством голосов.

Marc 07.11.2017 13:19

Да, мой тоже для .net 2.0.

John Demetriou 08.11.2017 14:44

Этот вопрос касается .NET 2.0, но он все еще появляется в поиске Google, и никто здесь не упомянул, что, начиная со стандарта .NET 1.1 / .NET core 1.0, теперь есть лучший способ узнать архитектуру процессора:

System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture

Теоретически это должно отличать x64 от Arm64, хотя я не тестировал это сам.

См. документация.

Другие вопросы по теме