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

269

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

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

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

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

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

Марк
источник

Ответы:

200

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

Как описывает Microsoft Раймонд Чен, вы должны сначала проверить, выполняется ли в 64-битном процессе (я думаю, что в .NET вы можете сделать это, проверив IntPtr.Size), и если вы работаете в 32-битном процессе, вы все равно должны вызвать функцию Win API IsWow64Process. Если это возвращает true, вы работаете в 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;
    }
}
Штефан Шульце
источник
7
При работе в 32-битной ОС любой вызов IsWow64Process вызовет исключение, так как эта запись отсутствует в kernel32.dll. Вам следует проверить решение, показанное в codeplex по адресу 1code.codeplex.com/SourceControl/changeset/view/39074#842775. У меня также есть решение на основе этого кода, указанного в нижней части этой страницы, которое использует методы расширения, если вы заботитесь о повторное использование кода.
dmihailescu
7
IsWow64Process был представлен с Win XP SP2. Этот код работает нормально, если вам требуется XP SP2 или более новая версия.
Марк
3
@dmihailescu, вы можете просто использовать DoesWin32MethodExist перед вызовом IsWow64Process, что и делает реализация .net 4.0 is64BitOperatingSystem.
Noobish
4
Ваше решение возвращает правильное значение на MacBook Pro с микропроцессором Intel i7-3720QM, работающим под Bootcamp с использованием раздела Widows 7 Ultimate. +1
Марк Крам
11
К вашему сведению: начиная с .Net 4.0 вы можете просто проверить System.Environment.Is64BitOperatingSystem. Вы можете отредактировать это в своем ответе или дать мне разрешение отредактировать его в своем ответе?
Джоэл Коухорн
242

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

Фил Девани
источник
5
Вместо Reflector, почему бы просто не скачать исходный код. Затем вы получите комментарии и другие «заметки».
AMissico
3
Согласно справочному источнику, он делает что-то вроде этого: if (IntPtr.Size == 8) return true; if(!DoesWin32MethodExist(...,"IsWow64Process")) return false; return IsWow64Process(GetCurrentProcess());(псевдокод)
Полином
5
Ницца. Если пользователь использует .NET 4.0, это, безусловно, правильный ответ (т.е. Environment.Is64BitOperatingSystem). - Свойство FYI, по-видимому, отсутствует в .NET 3.5.
BrainSlugs83
4
Это не отвечает на вопрос, который конкретно говорит .Net 2.0
abbottdev
.NET Core был выпущен под лицензией MIT, что означает, что вы можете прочитать исходный код для Is64BitProcessи Is64BitOperatingSystem(ссылки для версии 2.0).
Кристиан Чиупиту
51

Это всего лишь реализация того, что было предложено выше Бруно Лопесом, но работает на 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;
}
dwhiteho
источник
49

Полный ответ таков (взят из обоих ответов 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.

Бруно Лопес
источник
13
Это не удастся под Win2000 и WinXP SP1 и ранее. Вы должны проверить, существует ли функция IsWow64Process () перед ее вызовом, потому что она была представлена ​​только в XP SP2 и Vista / Win7.
user9876
2
@ user9876, (или) кто-то еще нацелился на эти античные системы?
CMircea
5
В этом примере не удается удалить экземпляр Process, возвращенный Process.GetCurrentProcess ().
Джо
42

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 (для тестирования удаленных машин).

synhershko
источник
1
Обратите внимание, что этот код лицензируется в рамках Microsoft Public License .
ladenedge
Версия WMI без управляемого .net? Я хотел бы видеть это, пока не нашел это
JohnZaj
16

Вы также можете проверить 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);
}
Эндрю Энсли
источник
1
То, что у вас 64-битный процессор, не означает, что у вас 64-битная операционная система
Дэвид
2
@David сообщает об архитектуре процессора Windows; не процессор. См. Подробное объяснение, начиная с «Кодекса» на этой странице: andrewensley.com/2009/06/c-detect-windows-os-part-1
Эндрю Энсли
Просто добавить 2 цента, при запуске этого, и ваше приложение настроено , чтобы prefer 32-bitс Any CPUкак ваш , Platform Targetто вы получите x86, но если вы снимите выделение Prefer 32-bitего вы потом получите AMD64.
XAMLMAX
14

Из блога Chriz Yuen

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

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

//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
electricalbah
источник
12

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

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

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

BobbyShaftoe
источник
32
Это не сработает - при работе в 32-битной .NET Framework 2.0 в 64-битной Windows вернется 32-битная.
Стефан Шульце
Хорошо, я забыл эту ситуацию. Я отредактировал вопрос, чтобы упомянуть об этом. Спасибо Стефан-мг.
Марк
1
Это не правильно; платформа может быть 64-битной, но вы все еще работаете в 32-битном режиме.
Себастьян Гуд
11

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

Environment.Is64BitOperatingSystem

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

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

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

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

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

System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")

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

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

Использование 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();
Александр
источник
6

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

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: Обнаружение битности процесса .

Santhosh
источник
Вы видели часть, где вопрос был о .NET, а не о C / C ++? И что это время компиляции против проверки во время выполнения. Кроме того, код выполняет присваивания, а не сравнения.
dvallejo
Этот код работает на .NET (протестировано на 2.0). Доступ к переменным Env можно получить: Environment.GetEnvironmentVariable ("PROCESSOR_ARCHITECTURE"); Environment.GetEnvironmentVariable ( "PROCESSOR_ARCHITEW6432");
andrew.fox
5

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

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

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

Александру Дику
источник
А что мешает мне , как пользователь с правами администратора от создания папки с именем SysWOW64на %windir%на 32 разрядной ОС? Наличие папки означает именно то, что папка присутствует.
cogumel0
Каковы шансы, что пользователь специально создаст такую ​​папку? Это просто другой способ проверить, является ли операционная система x64.
Александру Дику
Каковы шансы, что ваш компьютер заразится вирусом? Так как шансы довольно малы, лучше не устанавливать никакой защиты, тогда ... Программирование - это не создание чего-то, что имеет малые шансы на заведомо провал. Речь идет о создании чего-то, что имеет малые шансы неосознанно потерпеть неудачу - и затем исправить это. Первый называется плохим программированием / плохой реализацией, второй называется ошибкой.
cogumel0
@AlexandruDicu Вы должны упомянуть в ответе, что этот подход не является точным на 100% и все же есть риск неправильного вывода в случае, если папка специально создана каким-либо сторонним приложением или пользователем вручную.
Раджеш Мишра
4

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

    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;
        }
    }
Джулиан Холл
источник
4

Это решение основано на коде 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);  
}
dmihailescu
источник
Ссылка на CodePlex не работает.
Питер Мортенсен
3

Вот прямой подход в 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; 
} 
ripper234
источник
Вам все еще нужно сначала проверить размер указателя, иначе он просто проверяет, является ли это 32-битным процессом в 64-битной системе
Бруно Лопес
1
Также вылетает на старой ОС, так IsWow64Processкак не существует.
Полином
3

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

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

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

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

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

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

Все хорошо, но это также должно работать из env:

PROCESSOR_ARCHITECTURE=x86

..

PROCESSOR_ARCHITECTURE=AMD64

Слишком легко, может быть ;-)

Питер Мортенсен
источник
2

Вот подход инструментария управления 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:
user1054695
источник
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
источник
3
Это все хорошо, но этот класс взят из пространства имен Microsoft.UpdateServices.Administration, которое является Microsoft WSUS. Я не люблю включать эту ссылку, просто чтобы знать биты платформы.
Marc
"C: \ Program Files \ Microsoft.NET \ SDK \ v2.0 64bit \ LateBreaking \ PlatformInvoke \ WinAPIs \ OSInfo \ CS \ OSInfoCS.sln"
AMissico,
1

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

    [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";
Чудотворец
источник
0

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

string getOSArchitecture()
{
    string architectureStr;
    if (Directory.Exists(Environment.GetFolderPath(
                           Environment.SpecialFolder.ProgramFilesX86))) {
        architectureStr ="64-bit";
    }
    else {
        architectureStr = "32-bit";
    }
    return architectureStr;
}
user885959
источник
у меня нет свойства ProgramFilesX86 на w7x64 vs.net 2010
Кристиан Кашутт
0

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

например

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

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

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

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

Function Is64Bit() As Boolean

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

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

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

Джон
источник
5
Убедитесь, что вы получили правильное имя локализованного каталога из Win32 API, а не жестко его кодировали.
Кристиан Хейтер
Я бы сказал, что это хорошая идея, но вы не можете предположить, что пользователь никогда бы этого не сделал по какой-то непонятной причине.
GurdeepS
2
Некоторые плохо написанные приложения теперь устанавливаются непосредственно в «Program Files (x86)» независимо от архитектуры. У меня есть этот каталог на моей 32-битной машине, например, благодаря SOAPSonar.
ladenedge
-4

Я использую:

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:\.

Бен Г
источник
8
Очень плохой подход. Что если в будущем этот каталог будет переименован? Как насчет локализованной версии Windows? В Windows XP немецкий язык «Program Files» называется «Программа». Я не уверен, но XP 64 может, таким образом, назвать его «Программа (x86)».
Марк
1
Я не рекомендую этого, но вы можете обойти проблему локализации, расширив переменную среды% ProgramFiles (x86)%
Мэтью Локк,
-7

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

    public static bool Is64BitSystem()
    {
        if (Directory.Exists(Environment.GetEnvironmentVariable("Program Files (x86)"))) return true;
        else return false;
    }
мистифицировать
источник
6
Это не работает на неанглийских версиях XP из-за локализованного имени папки программ.
Даниэль Шлёссер
Но даже 64-битные системы имеют эту папку, ха-ха
carenownow1