Как определить Windows 64-битную платформу с .NET? - PullRequest
252 голосов
/ 03 декабря 2008

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

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

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

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

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

Ответы [ 29 ]

234 голосов
/ 16 декабря 2009

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

193 голосов
/ 03 декабря 2008

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;
    }
}
89 голосов
/ 29 августа 2012

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

Environment.Is64BitOperatingSystem

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

51 голосов
/ 03 декабря 2009

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

Полный ответ таков (взято как из stefan-mg, ripper234, так и из ответа Бобби Шафто):

    [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.

41 голосов
/ 16 августа 2010

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

16 голосов
/ 24 июня 2009

Вы также можете проверить переменную окружения 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);
}
12 голосов
/ 03 июня 2014

Из блога 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
11 голосов
/ 02 апреля 2013

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

Environment.Is64BitOperatingSystem

Environment.Is64BitProcess
10 голосов
/ 03 декабря 2008

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

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

Примечание: это очень прямо.

...