Làm cách nào để phát hiện nền tảng Windows 64 bit bằng .NET?


269

Trong ứng dụng .NET 2.0 C #, tôi sử dụng đoạn mã sau để phát hiện nền tảng hệ điều hành:

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

Điều này trả về "Win32NT". Vấn đề là nó trả về "Win32NT" ngay cả khi chạy trên Windows Vista 64-bit.

Có phương pháp nào khác để biết nền tảng chính xác (32 hoặc 64 bit) không?

Lưu ý rằng nó cũng sẽ phát hiện 64 bit khi chạy dưới dạng ứng dụng 32 bit trên Windows 64 bit.

Câu trả lời:


200

IntPtr.Size sẽ không trả về giá trị chính xác nếu chạy trong .NET Framework 2.0 32 bit trên Windows 64 bit (nó sẽ trả về 32 bit).

Như Raymond Chen của Microsoft mô tả, trước tiên bạn phải kiểm tra xem có đang chạy trong quy trình 64 bit không (tôi nghĩ trong .NET bạn có thể làm như vậy bằng cách kiểm tra IntPtr.Size) và nếu bạn đang chạy trong quy trình 32 bit, bạn vẫn phải gọi hàm Win API IsWow64Process. Nếu điều này trả về đúng, bạn đang chạy trong quy trình 32 bit trên Windows 64 bit.

Raymond Chen của Microsoft: Cách phát hiện lập trình cho dù bạn đang chạy trên Windows 64 bit

Giải pháp của tôi:

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
Khi chạy trên HĐH 32 bit, mọi cuộc gọi tới IsWow64Process sẽ đưa ra một ngoại lệ vì mục đó bị thiếu trong kernel32.dll. Bạn nên kiểm tra giải pháp được hiển thị từ codeplex tại 1code.codeplex.com/SourceControl/changeset/view/39074#842775. Tôi cũng có một giải pháp dựa trên mã được liệt kê ở cuối trang này, sử dụng các phương thức mở rộng nếu bạn quan tâm sử dụng lại mã.
dmihailescu

7
IsWow64Process được giới thiệu với Win XP SP2. Mã này hoạt động tốt nếu bạn yêu cầu XP SP2 hoặc bất kỳ phiên bản mới hơn.
Marc

3
@dmihailescu, bạn chỉ có thể sử dụng DoesWin32MethodExist trước khi gọi IsWow64Process, đây là điều mà triển khai .net 4.0 của is64BitOperatingSystem thực hiện.
noobish

4
Giải pháp của bạn trả về giá trị chính xác trên MacBook Pro với bộ vi xử lý Intel i7-3720QM chạy Bootcamp bằng phân vùng Widows 7 Ultimate. +1
Đánh dấu Kram

11
FYI: bắt đầu với .Net 4.0, bạn chỉ cần kiểm tra System.Environment.Is64BitOperatingSystem. Bạn có thể chỉnh sửa nó thành câu trả lời của bạn, hoặc cho phép tôi chỉnh sửa nó thành câu trả lời của bạn không?
Joel Coehoorn

242

.NET 4 có hai thuộc tính mới trong lớp Môi trường, Is64BitProcessIs64BitOperatingSystem . Thật thú vị, nếu bạn sử dụng Reflector, bạn có thể thấy chúng được triển khai khác nhau trong các phiên bản 32 bit & 64 bit của mscorlib. Phiên bản 32 bit trả về sai cho Is64BitProcess và gọi IsWow64Process qua P / Gọi cho Is64BitOperatingSystem. Phiên bản 64 bit chỉ trả về đúng cho cả hai.


5
Thay vì Reflector, tại sao không chỉ tải về nguồn. Sau đó, bạn nhận được các ý kiến ​​và "ghi chú" khác.
AMissico

3
Theo nguồn tham khảo, nó thực hiện một cái gì đó như thế này: if (IntPtr.Size == 8) return true; if(!DoesWin32MethodExist(...,"IsWow64Process")) return false; return IsWow64Process(GetCurrentProcess());(mã giả)
Đa thức

5
Đẹp. Nếu người dùng đang sử dụng .NET 4.0 thì đây chắc chắn là câu trả lời chính xác (ví dụ: Môi trường.Is64BitOperatingSystem). - Tài sản FYI dường như không có trong .NET 3.5.
BrainSlugs83

4
Điều này không trả lời câu hỏi cụ thể .Net 2.0
abbottdev 24/07/2015

.NET Core đã được phát hành theo giấy phép MIT, có nghĩa là bạn có thể đọc mã nguồn cho Is64BitProcessIs64BitOperatingSystem(liên kết cho phiên bản 2.0).
Cristian Ciupitu


51

Đây chỉ là một triển khai những gì được đề xuất ở trên bởi Bruno Lopez, nhưng hoạt động trên Win2k + tất cả các gói dịch vụ WinXP. Chỉ cần hình dung tôi sẽ đăng nó để người khác không phải cuộn nó bằng tay. (sẽ đăng dưới dạng nhận xét, nhưng tôi là người dùng mới!)

[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

Câu trả lời đầy đủ là đây (được lấy từ cả hai câu trả lời của stefan-mg, ripper234 và BobbyShaftoe):

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

Trước tiên hãy kiểm tra xem bạn có đang trong quá trình 64 bit không. Nếu bạn không phải, hãy kiểm tra xem quy trình 32 bit có phải là Wow64Process không.


13
Điều này sẽ thất bại trong Win2000 và WinXP SP1 trở về trước. Bạn cần kiểm tra xem hàm IsWow64Process () có tồn tại trước khi bạn gọi nó không, bởi vì nó chỉ được giới thiệu trong XP SP2 và Vista / Win7.
user9876

2
@ user9876, có ai (hoặc đã) vẫn nhắm mục tiêu các hệ thống cổ đó không?
CMircea

5
Mẫu này không thể loại bỏ đối tượng Process được trả về bởi Process.GetCienProcess ().
Joe

42

Microsoft đã đặt một mẫu mã cho việc này:

http://1code.codeplex.com/SourceControl/changeset/view/39074#842775

Nó trông như thế này:

    /// <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);

Cũng có sẵn phiên bản WMI (để thử nghiệm các máy từ xa).


1
Lưu ý rằng mã này được cấp phép theo Giấy phép Công cộng của Microsoft .
ladenedge

Phiên bản WMI không có .net được quản lý? Tôi muốn thấy rằng, đã không tìm thấy nó cho đến nay
JohnZaj

16

Bạn cũng có thể kiểm tra PROCESSOR_ARCHITECTUREbiến môi trường.

Nó không tồn tại hoặc được đặt thành "x86" trên Windows 32 bit.

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
Chỉ vì bạn có bộ xử lý 64 bit không có nghĩa là bạn có hệ điều hành 64 bit
David

2
@David Điều này báo cáo kiến ​​trúc bộ xử lý của Windows; không phải CPU. Xem giải thích chi tiết bắt đầu tại "Bộ luật" trên trang này: andrewensley.com/2009/06/c-detect-windows-os-part-1
Andrew Oblley

Chỉ cần thêm 2 cent, khi bạn chạy này, và ứng dụng của bạn được cấu hình để prefer 32-bitAny CPUnhư của bạn Platform Targetthì bạn sẽ nhận được x86, nhưng nếu bạn bỏ chọn Prefer 32-bitnó sau đó bạn sẽ nhận được AMD64.
XAMlMAX

14

Từ blog của Chriz Yuen

C # .Net 4.0 Giới thiệu hai thuộc tính môi trường mới Môi trường.Is64BitOperatingSystem; Môi trường.Is64BitProcess;

Hãy cẩn thận khi bạn sử dụng cả hai tài sản này. Kiểm tra trên máy Windows 7 64 bit

//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

Cách nhanh nhất:

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

Lưu ý: điều này rất trực tiếp và chỉ hoạt động chính xác trên 64 bit nếu chương trình không bắt buộc thực thi như một quy trình 32 bit (ví dụ: thông qua<Prefer32Bit>true</Prefer32Bit>trong cài đặt dự án).


32
Điều này sẽ không hoạt động - nếu chạy trong .NET Framework 2.0 32 bit trên Windows 64 bit, nó sẽ trả về 32 bit.
Stefan Schultze

Phải tôi quên tình huống này. Tôi đã chỉnh sửa câu hỏi để đề cập đến điều này là tốt. Cảm ơn stefan-mg.
Marc

1
Điều này LAF không đúng; nền tảng có thể là 64 bit nhưng bạn vẫn đang chạy ở chế độ 32 bit.
Sebastian Tốt

11

Thử cái này:

Environment.Is64BitOperatingSystem

Environment.Is64BitProcess

5
Cảm ơn cho đầu vào của bạn, nhưng xin vui lòng đọc các câu trả lời có sẵn trước khi đăng vì giải pháp này đã được đưa ra. Cũng lưu ý rằng câu hỏi ban đầu là về .net 2 không có hai thuộc tính này chỉ được giới thiệu với .net 4.
Marc

9

@foobar: Bạn nói đúng, quá dễ dàng;)

Trong 99% trường hợp, các nhà phát triển có nền tảng quản trị viên hệ thống yếu cuối cùng không nhận ra sức mạnh mà Microsoft luôn cung cấp cho bất kỳ ai để liệt kê Windows.

Quản trị viên hệ thống sẽ luôn viết mã tốt hơn và đơn giản hơn khi nói đến điểm như vậy.

Tuy nhiên, một điều cần lưu ý, cấu hình xây dựng phải là AnyCPU cho biến môi trường này để trả về các giá trị chính xác trên các hệ thống chính xác:

System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")

Điều này sẽ trả về "X86" trên Windows 32 bit và "AMD64" trên Windows 64 bit.


4
Giải pháp của bạn trả về x86 trên MacBook Pro với bộ vi xử lý Intel i7-3720QM chạy Bootcamp với phân vùng Widows 7 Ultimate. Giải pháp của Stefan Schultze xác định đúng bộ xử lý là 64 bit. Tôi chắc chắn rằng giải pháp của bạn hoạt động trên 99% máy tính chạy Windows hiện có. +1 để thử.
Đánh dấu Kram

Không. đã trả về "x86" trên Windows 7 pro, Hệ điều hành 64 bit của tôi.
Hagai L

7

Sử dụng dotPeek giúp xem khung công tác thực sự như thế nào. Với ý nghĩ đó, đây là những gì tôi nghĩ ra:

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

Ví dụ sử dụng:

EnvironmentHelper.Is64BitOperatingSystem();

6

Sử dụng hai biến môi trường này (mã giả):

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
        }

Tham khảo bài viết trên blog HOWTO: Phát hiện quá trình nhân chứng .


Bạn có thấy phần câu hỏi về .NET chứ không phải C / C ++ không? Và đây là thời gian biên dịch so với kiểm tra thời gian chạy. Ngoài ra, mã đang làm bài tập và không so sánh.
dvallejo

Mã này hoạt động trên .NET (được thử nghiệm trên 2.0). Các biến Env có thể được truy cập bởi: Môi trường.GetEn MôiVariable ("PROCESSOR_ARCHITECTURE"); Môi trường.GetEn Môi trường Biến đổi ("PROCESSOR_ARCHITEW6432");
andrew.fox

5

Tôi đã sử dụng kiểm tra này với thành công trên nhiều hệ điều hành:

private bool Is64BitSystem
{
   get
   {
      return Directory.Exists(Environment.ExpandEnvironmentVariables(@"%windir%\SysWOW64"));
   }
}

Thư mục này luôn được đặt tên là "SysWOW64", bất kể ngôn ngữ của hệ điều hành. Điều này hoạt động cho .NET Framework 1.1 trở lên.


Và điều gì ngăn cản tôi với tư cách là người dùng có quyền quản trị tạo thư mục được gọi SysWOW64trên %windir%hệ điều hành 32 bit? Sự hiện diện của một thư mục có nghĩa chính xác là: thư mục đó hiện diện.
cogumel0

Cơ hội mà người dùng sẽ tạo ra một thư mục như vậy có chủ đích là gì? Đây chỉ là một cách khác để kiểm tra xem hệ điều hành có phải là x64 không.
Alexandru Dicu

Cơ hội mà máy tính của bạn sẽ bị nhiễm virus là gì? Kể từ khi rất có thể là khá thấp, tốt hơn không cài đặt bất kỳ bảo vệ sau đó ... Lập trình không phải là về việc tạo ra một cái gì đó mà có cơ hội thấp của cố thất bại. Đó là về việc tạo ra thứ gì đó có khả năng thất bại thấp vô tình - và sau đó sửa nó. Đầu tiên được gọi là lập trình xấu / thực hiện xấu, thứ hai được gọi là một lỗi.
cogumel0

@AlexandruDicu Bạn nên đề cập trong câu trả lời rằng cách tiếp cận này không chính xác 100% và vẫn có nguy cơ đưa ra đầu ra sai trong trường hợp thư mục được tạo theo mục đích bởi bất kỳ ứng dụng hoặc người dùng bên thứ ba nào.
Rajesh Mishra

4

Tôi cần phải làm điều này, nhưng tôi cũng cần có khả năng là một quản trị viên thực hiện nó từ xa, trong trường hợp này có vẻ như hoạt động khá độc đáo đối với tôi:

    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

Đây là một giải pháp dựa trên mã của Microsoft tại http://1code.codeplex.com/SourceControl/changeset/view/39074#842775 . Nó sử dụng các phương thức mở rộng để tái sử dụng mã dễ dàng.

Một số cách sử dụng có thể được hiển thị dưới đây:

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);  
}

Liên kết CodePlex dường như bị hỏng.
Peter Mortensen

3

Đây là cách tiếp cận trực tiếp trong C # bằng cách sử dụng DLLImport từ trang này .

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

Trước tiên, bạn vẫn cần kiểm tra kích thước con trỏ, nếu không, nó chỉ kiểm tra xem đó có phải là quy trình 32 bit trên hệ thống 64 bit hay không
Bruno Lopes

1
Cũng gặp sự cố trên hệ điều hành cũ hơn, vì IsWow64Processkhông tồn tại.
Đa thức

3

Tôi đang sử dụng mã followin. Lưu ý: Nó được tạo cho một dự án 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

Tôi thấy đây là cách tốt nhất để kiểm tra nền tảng của hệ thống và quy trình:

bool 64BitSystem = Environment.Is64BitOperatingSystem;
bool 64BitProcess = Environment.Is64BitProcess;

Thuộc tính đầu tiên trả về true cho hệ thống 64 bit và false cho 32 bit. Thuộc tính thứ hai trả về true cho quá trình 64 bit và false cho 32 bit.

Sự cần thiết của hai thuộc tính này là bởi vì bạn có thể chạy các quy trình 32 bit trên hệ thống 64 bit, do đó bạn sẽ cần kiểm tra cả hệ thống và quy trình.


1
đặt một _ hoặc một chữ cái trước tên biến nếu bạn muốn nó được xây dựng trong c # (tên biến không bắt đầu bằng số trong c # theo như ide của tôi đang nói với tôi!)
Chris

2

Tất cả đều ổn, nhưng điều này cũng sẽ hoạt động từ env:

PROCESSOR_ARCHITECTURE=x86

..

PROCESSOR_ARCHITECTURE=AMD64

Quá dễ, có thể ;-)


2

Đây là cách tiếp cận Công cụ quản lý 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.

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
Điều đó thật tuyệt, nhưng lớp này là từ Microsoft.UpdateService. Không gian tên ứng dụng là Microsoft WSUS. Tôi không muốn bao gồm tài liệu tham khảo này chỉ để biết các bit nền tảng.
Marc

"C: \ Tệp chương trình \ Microsoft.NET \ SDK \ v2.0 64 bit \ lateBreaking \ PlatformInvoke \ WinAPIs \ OSInfo \ CS \ OSInfoCS.sln"
AMissico

1

Bao gồm các mã sau vào một lớp trong dự án của bạn:

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

Sử dụng nó như vậy:

string Architecture = "This is a " + GetBit() + "bit machine";

0

Sử dụng điều này để có được kiến ​​trúc Windows đã cài đặt:

string getOSArchitecture()
{
    string architectureStr;
    if (Directory.Exists(Environment.GetFolderPath(
                           Environment.SpecialFolder.ProgramFilesX86))) {
        architectureStr ="64-bit";
    }
    else {
        architectureStr = "32-bit";
    }
    return architectureStr;
}

tôi không có thuộc tính ProgramFilesX86 trên w7x64 vs.net 2010
Christian Casutt

0

Cho rằng câu trả lời được chấp nhận là rất phức tạp. Có những cách đơn giản hơn. Của tôi là một biến thể của anaswer alexandrudicu. Cho rằng các cửa sổ 64 bit cài đặt các ứng dụng 32 bit trong Tệp chương trình (x86), bạn có thể kiểm tra xem thư mục đó có tồn tại hay không, sử dụng các biến môi trường (để bù cho các nội địa hóa khác nhau)

ví dụ

private bool Is64BitSystem
{
   get
   {
      return Directory.Exists(Environment.ExpandEnvironmentVariables(@"%PROGRAMFILES(X86)%"));
   }
}

Điều này đối với tôi là nhanh hơn và đơn giản hơn. Cho rằng tôi cũng muốn truy cập một đường dẫn cụ thể trong thư mục đó dựa trên phiên bản HĐH.


2
Câu trả lời được chấp nhận là dành cho .NET 2.0. Nếu bạn đang sử dụng .NET 4.0 hoặc mới hơn, chỉ cần sử dụng Môi trường.Is64BitOperatingSystem như bạn có thể tìm thấy trong câu trả lời với hầu hết các phiếu bầu.
Marc

Vâng, của tôi là cho .net 2.0.
John Demetriou

-2

Thưởng thức ;-)

Function Is64Bit() As Boolean

    Return My.Computer.FileSystem.SpecialDirectories.ProgramFiles.Contains("Program Files (x86)")

End Function

-1 vì điều này sẽ không hoạt động trên các cài đặt Windows cục bộ. Và nó sử dụng VB.net trong khi câu hỏi được gắn thẻ cho C #.
Marc

-3

Chỉ cần xem "C: \ Program Files (x86)" có tồn tại không. Nếu không, thì bạn đang ở trên hệ điều hành 32 bit. Nếu vậy, HĐH là 64 bit (Windows Vista hoặc Windows 7). Có vẻ như đủ đơn giản ...


5
Đảm bảo bạn truy xuất đúng tên thư mục được bản địa hóa từ API Win32 thay vì mã hóa nó.
Christian Hayter

Tôi muốn nói rằng đó là một ý tưởng tốt, nhưng bạn không thể cho rằng người dùng sẽ không bao giờ làm điều này vì một lý do mơ hồ nào đó.
GurdeepS

2
Một số ứng dụng được viết kém hiện đang cài đặt trực tiếp vào "Tệp chương trình (x86)" mà không liên quan đến kiến ​​trúc. Tôi có thư mục đó trên máy 32 bit của mình, ví dụ như nhờ vào SOAPSonar.
ladenedge

-4

Tôi sử dụng:

Dim drivelet As String = Application.StartupPath.ToString
If Directory.Exists(drivelet(0) & ":\Program Files (x86)") Then
    MsgBox("64bit")
Else
    MsgBox("32bit")
End if

Điều này nhận được đường dẫn ứng dụng của bạn được khởi chạy trong trường hợp bạn đã cài đặt nó ở nhiều nơi trên máy tính. Ngoài ra, bạn chỉ có thể thực hiện C:\đường dẫn chung vì 99,9% máy tính ngoài đó đã cài đặt Windows C:\.


8
Cách tiếp cận rất tệ. Điều gì nếu trong tương lai thư mục này sẽ được đổi tên? Còn phiên bản Windows bản địa thì sao? Trong Windows XP, "Tệp chương trình" của Đức được gọi là "Chương trình". Tôi không chắc nhưng XP 64 có thể gọi nó là "Chương trình (x86)".
Marc

1
Tôi không khuyên bạn nhưng bạn có thể giải quyết vấn đề bản địa hóa bằng cách mở rộng var% ProgramFiles (x86)%
Matthew Lock

-7

Tôi sử dụng một phiên bản sau:

    public static bool Is64BitSystem()
    {
        if (Directory.Exists(Environment.GetEnvironmentVariable("Program Files (x86)"))) return true;
        else return false;
    }

6
Điều này không hoạt động trên các phiên bản XP không phải tiếng Anh vì tên Thư mục chương trình được bản địa hóa.
Daniel Schlößer

Nhưng ngay cả các hệ thống 64 bit cũng có thư mục này haha
cẩn thận1
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.