Як виявити 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.