Cách xác định theo chương trình xem một quy trình cụ thể là 32 bit hay 64 bit


102

Làm cách nào để ứng dụng C # của tôi có thể kiểm tra xem một ứng dụng / quy trình cụ thể (lưu ý: không phải quy trình hiện tại) đang chạy ở chế độ 32 bit hay 64 bit?

Ví dụ: tôi có thể muốn truy vấn một quy trình cụ thể theo tên, tức là 'abc.exe', hoặc dựa trên số ID quy trình.


Hãy luôn đặt ngôn ngữ dưới dạng thẻ; Tôi sẽ thay đổi điều đó ngay bây giờ trên bài đăng này. :-)
Dean J

3
Vui lòng làm rõ xem bạn muốn biết quy trình hiện tại là 64 bit hay bạn đang truy vấn quy trình khác?
Mehrdad Afshari

Câu trả lời:


177

Một trong những cách thú vị hơn mà tôi đã thấy là:

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

Để tìm hiểu xem các quy trình KHÁC có đang chạy trong trình giả lập 64 bit (WOW64) hay không, hãy sử dụng mã này:

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) Và đó là lý do tại sao Microsoft phải tạo ra các miếng dán tương thích nói dối phiên bản - để khắc phục các lỗi trong mã như vậy. Điều gì xảy ra khi Windows Vista (6.0) ra mắt? Và mọi người sau đó nói xấu Microsoft vì đã tạo ra Windows 7 phiên bản 6.1 thay vì 7.0, nó đã sửa rất nhiều lỗi tính năng ứng dụng.
Ian Boyd

4
Tên hàm IsWin64 hơi gây hiểu lầm, tôi nghĩ vậy. Nó trả về true nếu quá trình 32-bit đang chạy trên hệ điều hành x64.
Denis The Menace

2
Tại sao sử dụng processHandle = Process.GetProcessById(process.Id).Handle;thay vì chỉ processHandle = process.Handle;?
Jonathon Reinhart

1
@JonathonReinhart không phải đó chỉ là một câu hỏi hay. Tôi không có ý kiến. Nó phải là tiền đề từ việc chuyển đổi công việc theo cách này sang cách khác. Cảm ơn vì đã tìm thấy điều đó!
Jesse C. Slicer

1
Câu trả lời này không chính xác; và trả về false thay vì nêu ra một ngoại lệ trong trường hợp lỗi là một thiết kế rất tệ.
user626528

141

Nếu bạn đang sử dụng .Net 4.0, thì đó là một lớp lót cho quy trình hiện tại:

Environment.Is64BitProcess

Xem Môi trường.Is64BitProcessProperty (MSDN).


2
Bạn có thể đăng mã của Is64BitProcess? Có lẽ tôi có thể sử dụng những gì nó làm để tìm hiểu xem liệu tôi có đang chạy trong quá trình 64-bit hay không.
Ian Boyd

1
@Ian, tôi nghi ngờ Sam sẽ được phép đăng mã MS trên diễn đàn này một cách hợp pháp. Tôi không chắc về nội dung chính xác của giấy phép tham chiếu của họ, nhưng tôi khá chắc chắn rằng nó cấm sao chép mã ở bất kỳ đâu.
ProfK

3
@ Ai đó đã làm công việc đó cho bạn: stackoverflow.com/questions/336633/…
Robert MacLean

4
OP đã yêu cầu cụ thể để truy vấn một quy trình khác , không phải quy trình hiện tại.
Harry Johnston

1
Lưu ý rằng Microsoft đã đăng mã cho Is64BitProcess( referenceource.microsoft.com/#mscorlib/system/enosystem.cs ). Tuy nhiên, nó chỉ là một câu lệnh trả về được mã hóa cứng, được điều khiển bởi ký hiệu biên dịch.
Brian

20

Câu trả lời đã chọn không chính xác vì nó không thực hiện những gì được hỏi. Nó kiểm tra xem một quá trình có phải là một quá trình x86 chạy trên hệ điều hành x64 hay không; vì vậy nó sẽ trả về "false" cho quy trình x64 trên hệ điều hành x64 hoặc quy trình x86 chạy trên hệ điều hành x86.
Ngoài ra, nó không xử lý lỗi một cách chính xác.

Đây là một phương pháp đúng hơn:

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"sẽ luôn trả về true cho quá trình 32 bit. Tốt hơn để sử dụng System.Environment.Is64BitOperatingSystemnếu .NET4 được hỗ trợ
Aizzat Suhardi

10

Bạn có thể kiểm tra kích thước của một con trỏ để xác định xem nó là 32bits hay 64bits.

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

6
Vào thời điểm câu trả lời này được đăng lần đầu tiên, nó không rõ ràng lắm, nhưng OP muốn biết cách truy vấn quy trình khác chứ không phải quy trình hiện tại.
Harry Johnston

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 đã hỏi cụ thể cách truy vấn quy trình khác , không phải quy trình hiện tại.
Harry Johnston

1

Đây là kiểm tra một dòng.

bool is64Bit = IntPtr.Size == 8;

6
OP đã hỏi cụ thể cách truy vấn quy trình khác , không phải quy trình hiện tại.
Harry Johnston

0

Tôi thích sử dụng cái này:

string e = Environment.Is64BitOperatingSystem

Bằng cách này, nếu tôi cần tìm hoặc xác minh tệp, tôi có thể dễ dàng ghi:

string e = Environment.Is64BitOperatingSystem

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

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

13
những gì về quá trình 32 bit trong máy hệ điều hành 64 bit?
Kiquenet

3
Nó có thực sự khó sử dụng Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)thay vì mã hóa cứng `C: \ Program Files` không?
Luaan

2
Không bao giờ viết mã cứng "tệp chương trình", vì đó là một chuỗi có thể bản địa hóa. Αρχεία Εφαρμογών, Arquivos de Programas, v.v.
stevieg
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.