Как программно определить, является ли конкретный процесс 32-битным или 64-битным


102

Как мое приложение C # может проверить, работает ли конкретное приложение / процесс (примечание: не текущий процесс) в 32-битном или 64-битном режиме?

Например, мне может потребоваться запросить конкретный процесс по имени, например «abc.exe», или на основе идентификационного номера процесса.


Пожалуйста, всегда указывайте язык как тег; Я изменю это сейчас в этом посте. :-)
Dean J

3
Уточните, хотите ли вы знать, что текущий процесс - 64-битный, или вы запрашиваете другой процесс?
Mehrdad Afshari

Ответы:


177

Я видел один из наиболее интересных способов:

if (IntPtr.Size == 4)
{
    // 32-bit
}
else if (IntPtr.Size == 8)
{
    // 64-bit
}
else
{
    // The future is now!
}

Чтобы узнать, запущены ли ДРУГИЕ процессы в 64-битном эмуляторе (WOW64), используйте этот код:

namespace Is64Bit
{
    using System;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Runtime.InteropServices;

    internal static class Program
    {
        private static void Main()
        {
            foreach (var p in Process.GetProcesses())
            {
                try
                {
                    Console.WriteLine(p.ProcessName + " is " + (p.IsWin64Emulator() ? string.Empty : "not ") + "32-bit");
                }
                catch (Win32Exception ex)
                {
                    if (ex.NativeErrorCode != 0x00000005)
                    {
                        throw;
                    }
                }
            }

            Console.ReadLine();
        }

        private static bool IsWin64Emulator(this Process process)
        {
            if ((Environment.OSVersion.Version.Major > 5)
                || ((Environment.OSVersion.Version.Major == 5) && (Environment.OSVersion.Version.Minor >= 1)))
            {
                bool retVal;

                return NativeMethods.IsWow64Process(process.Handle, out retVal) && retVal;
            }

            return false; // not on 64-bit Windows Emulator
        }
    }

    internal static class NativeMethods
    {
        [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool IsWow64Process([In] IntPtr process, [Out] out bool wow64Process);
    }
}

8
(Environment.OSVersion.Version.Major >= 5 && Environment.OSVersion.Version.Minor >= 1) Вот почему Microsoft должна создать прокладки совместимости с ложными версиями - чтобы обойти подобные ошибки в коде. Что произойдет, когда выйдет Windows Vista (6.0)? А потом люди ругают Microsoft за то, что она делает Windows 7 версии 6.1, а не 7.0, она исправляет так много ошибок совместимости приложений.
Ян Бойд,

4
Я думаю, что имя функции IsWin64 немного вводит в заблуждение. Он возвращает истину, если 32-битный процесс работает под ОС x64.
Denis The Menace

2
Зачем использовать processHandle = Process.GetProcessById(process.Id).Handle;вместо просто processHandle = process.Handle;?
Jonathon Reinhart

1
@JonathonReinhart ну, это не просто хороший вопрос. Я понятия не имею. Должно быть, это было рудиментарным от смены одного способа на другой. Спасибо, что нашли это!
Джесси С. Слайсер

1
Этот ответ неверен; и возвращать false вместо вызова исключения в случае ошибки - очень плохой дизайн.
user626528

141

Если вы используете .Net 4.0, это однострочный вариант для текущего процесса:

Environment.Is64BitProcess

См. Environment.Is64BitProcessProperty (MSDN).


2
Не могли бы вы выложить код Is64BitProcess? Возможно, я смогу использовать то, что он делает, чтобы выяснить, работаю ли я как 64-битный процесс.
Ян Бойд,

1
@Ian, я сомневаюсь, что Сэму будет законно разрешено публиковать MS-код на этом форуме. Я не уверен в точном содержании их эталонной лицензии, но уверен, что она запрещает воспроизведение кода где угодно.
ProfK

3
@Ian кто-то проделал эту работу за вас: stackoverflow.com/questions/336633/…
Роберт Маклин

4
OP специально попросил запросить другой процесс, а не текущий процесс.
Гарри Джонстон

1
Обратите внимание , что Microsoft сделал опубликовать код Is64BitProcess( referencesource.microsoft.com/#mscorlib/system/environment.cs ). Однако это просто жестко запрограммированный оператор возврата, управляемый символом компиляции.
Брайан

20

Выбранный ответ неверен, так как он не соответствует тому, о чем просили. Вместо этого он проверяет, является ли процесс процессом x86, работающим в ОС x64; поэтому он вернет "false" для процесса x64 в ОС x64 или процесса x86, запущенного в ОС x86.
Кроме того, он неправильно обрабатывает ошибки.

Вот более правильный способ:

internal static class NativeMethods
{
    // see https://msdn.microsoft.com/en-us/library/windows/desktop/ms684139%28v=vs.85%29.aspx
    public static bool Is64Bit(Process process)
    {
        if (!Environment.Is64BitOperatingSystem)
            return false;
        // if this method is not available in your version of .NET, use GetNativeSystemInfo via P/Invoke instead

        bool isWow64;
        if (!IsWow64Process(process.Handle, out isWow64))
            throw new Win32Exception();
        return !isWow64;
    }

    [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool IsWow64Process([In] IntPtr process, [Out] out bool wow64Process);
}

1
Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE") == "x86"всегда будет возвращать истину для 32-битного процесса. Лучше использовать, System.Environment.Is64BitOperatingSystemесли поддерживается
.NET4

10

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

int bits = IntPtr.Size * 8;
Console.WriteLine( "{0}-bit", bits );
Console.ReadLine();

6
В то время, когда этот ответ был впервые опубликован, он не был очень ясным, но OP хотел знать, как запросить другой процесс, а не текущий процесс.
Гарри Джонстон

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

5
OP специально спросил, как запросить другой процесс, а не текущий процесс.
Гарри Джонстон


0

Мне нравится использовать это:

string e = Environment.Is64BitOperatingSystem

Таким образом, если мне нужно найти или проверить файл, я могу легко написать:

string e = Environment.Is64BitOperatingSystem

       // If 64 bit locate the 32 bit folder
       ? @"C:\Program Files (x86)\"

       // Else 32 bit
       : @"C:\Program Files\";

13
как насчет 32-битного процесса на 64-битной машине с ОС?
Kiquenet

3
Неужели так сложно использовать Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)вместо жесткого программирования `C: \ Program Files`?
Луаан

2
Никогда не кодируйте «программные файлы» жестко, потому что это локализуемая строка. Αρχεία Εφαρμογών, Arquivos de Programas, и т. Д.
Stevieg
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.