Як виявити 64-бітну платформу Windows за допомогою .NET?


268

У додатку .NET 2.0 C # я використовую такий код для виявлення платформи операційної системи:

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

Це повертає "Win32NT". Проблема полягає в тому, що він повертає "Win32NT" навіть під час роботи на Windows Vista 64-розрядної.

Чи є якийсь інший спосіб знати правильну платформу (32 або 64 біт)?

Зауважте, що він також повинен виявити 64-бітний при запуску як 32-бітний додаток у Windows 64-бітному.

Відповіді:


200

IntPtr.Size не поверне правильне значення, якщо він працює в 32-розрядному .NET Framework 2.0 для 64-розрядних Windows (він поверне 32-бітний).

Як описує Реймонд Чен від Microsoft, спочатку ви повинні перевірити, чи працює він у 64-бітному процесі (я думаю, що в .NET ви можете це зробити, перевіривши IntPtr.Size), і якщо ви працюєте в 32-бітному процесі, ви все одно доведеться викликати функцію Win API IsWow64Process. Якщо це повертає справжнє значення, ви працюєте в 32-бітному процесі в 64-розрядної Windows.

Реймон Чен від Майкрософт: Як програмно визначити, чи працюєте ви на 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
FYI: починаючи з .Net 4.0 ви можете просто перевірити System.Environment.Is64BitOperatingSystem. Чи можете ви відредагувати це у своїй відповіді чи дозволити мені редагувати це у вашій відповіді?
— Joel Coehoorn

241

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


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

49

Повна відповідь така (взята як зі стефану-мг, ріппера234, так і з відповіді БобіШафтоя):

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


1
Зауважте, що цей код ліцензований відповідно до публічної ліцензії Microsoft .
— 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

З блогу Кріз Юен

C # .Net 4.0 Представлено два нові властивості середовища Environment.Is64BitOperatingSystem; Середовище.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

12

Найшвидший спосіб:

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

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


32
Це не буде працювати - якщо він працює в 32-розрядному .NET Framework 2.0 в 64-бітній Windows, він повернеться 32-бітний.
— Стефан Шульце

Правильно я забув цю ситуацію. Я редагував питання, щоб згадати і про це. Завдяки стефану-мг.
— Марк

1
Це неправильно; платформа може мати 64 біти, але ви все ще працюєте в 32-бітному режимі.
— Себастьян Добрий

11

Спробуйте це:

Environment.Is64BitOperatingSystem

Environment.Is64BitProcess

5
Дякуємо за ваш внесок, але прочитайте доступні відповіді перед публікацією, оскільки це рішення вже надано. Також зауважте, що оригінальне питання стосувалося .net 2, у якого немає цих двох властивостей, які були введені лише з .net 4.
— Марк

9

@foobar: Ти маєш рацію, це занадто просто;)

У 99% випадків розробники зі слабким фоном системного адміністратора, нарешті, не усвідомлюють потужність, яку Microsoft завжди забезпечувала для перерахування Windows.

Системні адміністратори завжди будуть писати кращий і простіший код, коли мова йде про такий момент.

Однак слід зазначити одне, що конфігурація збірки повинна бути AnyCPU для цієї змінної середовища для повернення правильних значень у правильних системах:

System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")

Це поверне "X86" у 32-розрядної Windows, а "AMD64" на 64-бітній Windows.


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

Ні. повернув "x86" на 64-бітній операційній системі Windows 7 pro.
— Хагай 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: Виявлення Bitness процесу .


Ви бачили ту частину, де було питання про .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);  
}

Здається, посилання 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; 
} 

Вам потрібно спочатку перевірити розмір вказівника, інакше він просто перевіряє, чи це 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-бітній системі, тому вам потрібно буде перевірити як систему, так і процес.


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:

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

3
Це все добре, але цей клас походить з простору імен Microsoft.UpdateServices.Administration, який є Microsoft WSUS. Мені не подобається включати цю посилання лише для того, щоб знати біти платформи.
— Марк

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

у мене немає властивості ProgramFilesX86 на w7x64 vs.net 2010
— Christian Casutt

0

Враховуючи, що прийнята відповідь дуже складна. Є більш прості способи. Шахта - це зміна відповіді александрудіку. Зважаючи на те, що 64-розрядні вікна встановлюють 32-розрядні програми в програмні файли (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

-1, оскільки це не працюватиме на локалізованих установках Windows. І він використовує VB.net, тоді як питання позначено як C #.
— Марк

-3

Просто подивіться, чи існує "C: \ Program Files (x86)". Якщо ні, то ви перебуваєте на 32-бітної ОС. Якщо це так, то ОС має 64 біт (Windows Vista або Windows 7). Це здається досить простим ...


5
Переконайтеся, що ви отримали правильне ім’я локалізованої каталоги з API Win32 замість жорсткого кодування.
— Крістіан Хейтер

Я б сказав, що це гарна ідея, але ви не можете припустити, що користувач ніколи цього не зробить з якихось незрозумілих причин.
— GurdeepS

2
Деякі програми, які погано написані, зараз встановлюються безпосередньо у "Програмні файли (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 німецька "Файли програм" називається "Програма". Я не впевнений, але XP 64, таким чином, може називати його "Програма (x86)".
— Марк

1
Я не рекомендую, але ви можете обійти проблему локалізації, розширивши екологічну var% ProgramFiles (x86)%
— Matthew Lock,

-7

Я використовую версію наступного:

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

6
Це не працює у не англійських версіях XP через локалізовану назву папок програми.
— Даніель Шльоссер

Але навіть у 64-бітових системах є ця папка ха-ха
— внимательно1
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.