Як визначити програмно, чи є той чи інший процес 32-розрядним чи 64-бітним


102

Як моя програма C # може перевірити, чи працює певна програма / процес (зауважте: не поточний процес) у 32-бітному або 64-бітному режимі?

Наприклад, я б хотів запитати певний процес за назвою, наприклад, 'abc.exe', або на основі ідентифікаційного номера процесу.


Будь ласка, завжди кладіть мову як тег; Я зараз це зміню на цій посаді. :-)
Дін J

3
Поясніть, будь ласка, чи хочете ви знати, що поточний процес є 64-бітовим чи ви запитуєте інший процес?
Мехрдад Афшарі

Відповіді:


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-бітний процес працює в ОС 64 x.
Денис Грозний

2
Навіщо використовувати processHandle = Process.GetProcessById(process.Id).Handle;замість просто processHandle = process.Handle;?
Джонатан Райнхарт

1
@JonathonReinhart добре, це не лише гарне питання. Я поняття не маю. Це, мабуть, було невдоволено від того, щоб переходити робити речі в одну сторону до іншої. Дякуємо, що знайшли це!
Джессі К. Слікер

1
Ця відповідь просто неправильна; і повернення помилки замість того, щоб збільшувати виняток у випадку помилки, дуже погана конструкція.
користувач626528

141

Якщо ви використовуєте .Net 4.0, це поточний процес для однієї лінії:

Environment.Is64BitProcess

Див. Середовище.Is64BitProcessProperty (MSDN).


2
Чи можете ви опублікувати код Is64BitProcess? Можливо, я можу використати те, що він робить, щоб зрозуміти, якщо я працюю як 64-бітний процес.
Ян Бойд

1
@Ian, я сумніваюся, що Сейму було б дозволено публікувати MS-код на цьому форумі. Я не впевнений у точному вмісті їх довідкової ліцензії, але я впевнений, що це забороняє відтворення коду в будь-якому місці.
ПрофК

3
@Як хтось зробив цю роботу за вас: stackoverflow.com/questions/336633/…
Роберт Маклін

4
ОП спеціально попросила запитувати інший процес, а не поточний процес.
Гаррі Джонстон

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

20

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

Ось більш правильний метод:

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
На той момент, коли ця відповідь була вперше опублікована, це було не дуже зрозуміло, але ОП хотіло знати, як запросити інший процес, а не поточний процес.
Гаррі Джонстон

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
ОП спеціально запитала, як запитувати інший процес, а не поточний процес.
Гаррі Джонстон


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-бітній ОС-машині?
Кікенет

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.