【问题标题】:How to detect Windows 64-bit platform with .NET?如何使用 .NET 检测 Windows 64 位平台?
【发布时间】:2010-09-25 02:20:36
【问题描述】:

.NET 2.0 C# 应用程序中,我使用以下代码检测操作系统平台:

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

这将返回“Win32NT”。问题是即使在 64 位 Windows Vista 上运行它也会返回“Win32NT”。

还有其他方法可以知道正确的平台(32 位还是 64 位)?

请注意,在 Windows 64 位上作为 32 位应用程序运行时,它也应该检测 64 位。

【问题讨论】:

    标签: c# windows 64-bit .net-2.0 platform-detection


    【解决方案1】:

    .NET 4 在 Environment 类中有两个新属性,Is64BitProcessIs64BitOperatingSystem。有趣的是,如果您使用 Reflector,您会发现它们在 32 位和 64 位版本的 mscorlib 中的实现方式不同。 32 位版本为 Is64BitProcess 返回 false,并通过 P/Invoke 为 Is64BitOperatingSystem 调用 IsWow64Process。 64 位版本只为两者返回 true。

    【讨论】:

    • 为什么不直接下载源代码,而不是 Reflector。然后你会得到 cmets 和其他“笔记”。
    • 根据参考来源,它做了这样的事情:if (IntPtr.Size == 8) return true; if(!DoesWin32MethodExist(...,"IsWow64Process")) return false; return IsWow64Process(GetCurrentProcess());(伪代码)
    • 不错。如果用户使用的是 .NET 4.0,这绝对是正确的答案(即 Environment.Is64BitOperatingSystem)。 -- FYI 属性在 .NET 3.5 中似乎不存在。
    • 这没有回答具体说 .Net 2.0 的问题
    • .NET Core 已在 MIT 许可下发布,这意味着您可以阅读 Is64BitProcessIs64BitOperatingSystem 的源代码(2.0 版链接)。
    【解决方案2】:

    更新:正如 Joel Coehoorn 和其他人所建议的,从 .NET Framework 4.0 开始,您只需检查 Environment.Is64BitOperatingSystem


    如果在 64 位 Windows 上的 32 位 .NET Framework 2.0 中运行,IntPtr.Size 将不会返回正确的值(它将返回 32 位)。

    正如微软的 Raymond Chen 所描述的,你必须首先检查是否在 64 位进程中运行(我认为在 .NET 中你可以通过检查 IntPtr.Size 来做到这一点),以及你是否在 32 位进程中运行,您仍然需要调用 Win API 函数 IsWow64Process。如果返回 true,则您正在 64 位 Windows 上的 32 位进程中运行。

    微软的 Raymond Chen: How to detect programmatically whether you are running on 64-bit 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;
        }
    }
    

    【讨论】:

    • 在 32 位操作系统上运行时,对 IsWow64Process 的任何调用都会引发异常,因为 kernel32.dll 中缺少该条目。您应该在1code.codeplex.com/SourceControl/changeset/view/39074#842775 处查看 codeplex 显示的解决方案。我还有一个基于此页面底部列出的代码的解决方案,如果您关心重用代码,它会使用扩展方法。
    • IsWow64Process 是在 Win XP SP2 中引入的。如果您需要 XP SP2 或任何更新版本,此代码可以正常工作。
    • @dmihailescu,你可以在调用 IsWow64Process 之前使用 DoesWin32MethodExist,这是 is64BitOperatingSystem 的 .net 4.0 实现所做的。
    • 您的解决方案在配备 Intel i7-3720QM 微处理器并使用 Widows 7 Ultimate 分区运行 Bootcamp 的 MacBook Pro 上返回正确值。 +1
    • 仅供参考:从 .Net 4.0 开始,您只需检查 System.Environment.Is64BitOperatingSystem。您可以将其编辑到您的答案中,还是允许我将其编辑到您的答案中?
    【解决方案3】:

    如果您使用的是.NET Framework 4.0,这很容易:

    Environment.Is64BitOperatingSystem
    

    请参阅 Environment.Is64BitOperatingSystem Property (MSDN)。

    【讨论】:

    【解决方案4】:

    这只是 Bruno Lopez 上述建议的一个实现,但适用于 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;
    }
    

    【讨论】:

      【解决方案5】:

      完整的答案是这样的(取自 stefan-mg、ripper234 和 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;
          } 
      

      首先检查您是否处于 64 位进程中。如果不是,请检查 32 位进程是否为 Wow64Process。

      【讨论】:

      • 这将在 Win2000 和 WinXP SP1 及更早版本下失败。调用 IsWow64Process() 函数之前需要检查它是否存在,因为它只在 XP SP2 和 Vista/Win7 中引入。
      • @user9876,是否(或曾经)仍然有人瞄准那些古董系统?
      • 此示例无法处理 Process.GetCurrentProcess() 返回的 Process 实例。
      【解决方案6】:

      微软为此提供了一个代码示例:

      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 版本(用于测试远程机器)。

      【讨论】:

      • 请注意,此代码已在Microsoft Public License 下获得许可。
      • 没有托管 .net 的 WMI 版本?我想看看,目前还没找到
      【解决方案7】:

      您还可以检查PROCESSOR_ARCHITECTURE 环境变量。

      它要么不存在,要么在 32 位 Windows 上设置为“x86”。

      private int GetOSArchitecture()
      {
          string pa = 
              Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE");
          return ((String.IsNullOrEmpty(pa) || 
                   String.Compare(pa, 0, "x86", 0, 3, true) == 0) ? 32 : 64);
      }
      

      【讨论】:

      • 拥有 64 位处理器并不意味着您拥有 64 位操作系统
      • @David 这个报告Windows的处理器架构;不是 CPU。请参阅本页“代码”开始的详细说明:andrewensley.com/2009/06/c-detect-windows-os-part-1
      • 只需添加 2 美分,当您运行此程序时,您的应用程序配置为 prefer 32-bitAny CPU 作为您的 Platform Target,那么您将获得 x86,但如果您取消选中 @ 987654328@,然后您将获得AMD64
      【解决方案8】:

      来自 Chriz Yuen 博客

      C# .Net 4.0 引入了两个新的环境属性 Environment.Is64Bit操作系统; Environment.Is64BitProcess;

      使用这两个属性时请小心。 在 Windows 7 64 位机器上测试

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

      【讨论】:

        【解决方案9】:

        最快的方法:

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

        注意:这是非常直接的,并且仅当程序不强制执行为 32 位进程时(例如通过 &lt;Prefer32Bit&gt;true&lt;/Prefer32Bit&gt;在项目设置中)。

        【讨论】:

        • 这不起作用 - 如果在 64 位 Windows 上运行 32 位 .NET Framework 2.0,它将返回 32 位。
        • 对我忘了这个情况。我也编辑了这个问题来提及这一点。谢谢 stefan-mg。
        • 这是不正确的;平台可能是 64 位,但您仍然在 32 位模式下运行。
        【解决方案10】:

        试试这个:

        Environment.Is64BitOperatingSystem
        
        Environment.Is64BitProcess
        

        【讨论】:

        • 感谢您的输入,但请在发布之前阅读可用的答案,因为此解决方案已经给出。另请注意,最初的问题是关于 .net 2 的,它不具有仅在 .net 4 中引入的这两个属性。
        【解决方案11】:

        @foobar:你说得对,这太容易了;)

        在 99% 的情况下,系统管理员背景薄弱的开发人员最终无法意识到微软一直为任何人提供枚举 Windows 的能力。

        在这种情况下,系统管理员总是会编写更好、更简单的代码。

        不过,需要注意的一点是,构建配置必须是 AnyCPU,这样环境变量才能在正确的系统上返回正确的值:

        System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")
        

        这将在 32 位 Windows 上返回“X86”,在 64 位 Windows 上返回“AMD64”。

        【讨论】:

        • 您的解决方案在配备 Intel i7-3720QM 微处理器的 MacBook Pro 上返回 x86,该微处理器运行带有 Widows 7 Ultimate 分区的 Bootcamp。 Stefan Schultze 的解决方案正确地将处理器识别为 64 位。我确信您的解决方案适用于 99% 的基于 Windows 的 PC。 +1 尝试。
        • 不。在我的 windows 7 pro 64 位操作系统上返回“x86”。
        【解决方案12】:

        使用dotPeek 有助于了解框架实际上是如何做到的。考虑到这一点,这就是我想出的:

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

        示例用法:

        EnvironmentHelper.Is64BitOperatingSystem();
        

        【讨论】:

          【解决方案13】:

          使用这两个环境变量(伪代码):

          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
                  }
          

          参考博文HOWTO: Detect Process Bitness

          【讨论】:

          • 您是否看到问题是关于 .NET 而不是 C/C++ 的部分?这是编译时间与运行时检查。另外,代码是在做赋值而不是比较。
          • 此代码适用于 .NET(在 2.0 上测试)。环境变量可以通过以下方式访问:Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE"); Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432");
          【解决方案14】:

          我在许多操作系统上都成功地使用了这个检查:

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

          无论操作系统的语言如何,此文件夹始终命名为“SysWOW64”。这适用于 .NET Framework 1.1 或更高版本。

          【讨论】:

          • 作为一个拥有管理权限的用户,是什么阻止我在 32 位操作系统上的 %windir% 上创建一个名为 SysWOW64 的文件夹?文件夹的存在意味着:该文件夹存在。
          • 用户故意创建这样一个文件夹的可能性有多大?这只是检查操作系统是否为 x64 的另一种方法。
          • 您的计算机感染病毒的可能性有多大?由于机会非常低,因此最好不要安装任何保护措施……编程并不是要创建故意失败的可能性很小的东西。这是关于创建一些在不知不觉中失败的可能性很小的东西 - 然后修复它。第一个称为糟糕的编程/糟糕的实现,第二个称为错误。
          • @AlexandruDicu 您应该在答案中提到,这种方法并非 100% 准确,并且如果文件夹是由任何第三方应用程序或用户手动创建的,仍然存在提供错误输出的风险。跨度>
          【解决方案15】:

          我需要这样做,但我还需要能够以管理员的身份远程进行,无论哪种情况,这对我来说似乎都很好:

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

          【讨论】:

            【解决方案16】:

            这是一个基于 Microsoft 代码 http://1code.codeplex.com/SourceControl/changeset/view/39074#842775 的解决方案。它使用扩展方法方便代码重用。

            一些可能的用法如下所示:

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

            【讨论】:

            • CodePlex 链接似乎已损坏。
            【解决方案17】:

            这是在 C# 中使用来自this page 的 DllImport 的直接方法。

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

            【讨论】:

            • 你还是需要先检查指针大小,否则它只是检查它是否是64位系统上的32位进程
            • 在旧操作系统上也会崩溃,因为IsWow64Process 不存在。
            【解决方案18】:

            我正在使用以下代码。 注意:它是为 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);
                }
            

            【讨论】:

              【解决方案19】:

              我发现这是检查系统平台和进程的最佳方法:

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

              第一个属性对于 64 位系统返回 true,对于 32 位系统返回 false。 第二个属性对于 64 位进程返回 true,对于 32 位返回 false。

              需要这两个属性是因为你可以在 64 位系统上运行 32 位进程,所以你需要同时检查系统和进程。

              【讨论】:

              • 如果你想在 c# 中构建变量名,请在变量名前面加上一个 _ 或一个字母(就我的想法而言,变量名在 c# 中不以数字开头!)
              【解决方案20】:

              一切都好,但这也应该适用于env

              PROCESSOR_ARCHITECTURE=x86
              

              ..

              PROCESSOR_ARCHITECTURE=AMD64
              

              太容易了,也许;-)

              【讨论】:

                【解决方案21】:

                这是Windows Management Instrumentation (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:
                

                【讨论】:

                  【解决方案22】:

                  OSInfo.Bits

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

                  【讨论】:

                  • 这很好,但是这个类来自 Microsoft.UpdateServices.Administration 命名空间,即 Microsoft WSUS。我不想仅仅为了了解平台位而包含此参考。
                  • "C:\Program Files\Microsoft.NET\SDK\v2.0 64bit\LateBreaking\PlatformInvoke\WinAPIs\OSInfo\CS\OSInfoCS.sln"
                  【解决方案23】:

                  将以下代码包含到项目中的类中:

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

                  像这样使用它:

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

                  【讨论】:

                    【解决方案24】:

                    使用它来获取已安装的 Windows 架构:

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

                    【讨论】:

                    • 我在 w7x64 vs.net 2010 上没有 ProgramFilesX86 属性
                    【解决方案25】:

                    鉴于接受的答案非常复杂。有更简单的方法。我的是 alexandrudicu 回答的变体。 鉴于 64 位 Windows 在 Program Files (x86) 中安装 32 位应用程序,您可以使用环境变量检查该文件夹是否存在(以弥补不同的本地化)

                    例如

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

                    这对我来说更快更简单。鉴于我还希望根据操作系统版本访问该文件夹下的特定路径。

                    【讨论】:

                    • 接受的答案是针对 .NET 2.0。如果您使用的是 .NET 4.0 或更高版本,只需使用 Environment.Is64BitOperatingSystem 即可,因为您可以在投票最多的答案中找到。
                    • 是的,我的也是.net 2.0。
                    【解决方案26】:

                    这个问题是针对 .NET 2.0 但仍然出现在 google 搜索中,这里没有人提到自从 .NET 标准 1.1 / .NET core 1.0 以来,现在有更好的方法来了解 CPU 架构:

                    System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture
                    

                    这理论上应该可以区分 x64 和 Arm64,虽然我自己没有测试。

                    the documentation

                    【讨论】:

                      【解决方案27】:

                      享受 ;-)

                      Function Is64Bit() As Boolean
                      
                          Return My.Computer.FileSystem.SpecialDirectories.ProgramFiles.Contains("Program Files (x86)")
                      
                      End Function
                      

                      【讨论】:

                      • -1 因为这不适用于本地化的 Windows 安装。它使用 VB.net,而问题被标记为 C#。
                      【解决方案28】:

                      看看“C:\Program Files (x86)”是否存在。如果不是,那么您使用的是 32 位操作系统。如果是,则操作系统为 64 位(Windows Vista 或 Windows 7)。看起来很简单……

                      【讨论】:

                      • 确保从 Win32 API 检索正确的本地化目录名称,而不是对其进行硬编码。
                      • 我会说这是个好主意,但你不能假设用户永远不会出于某种模糊的原因这样做。
                      • 一些写得不好的应用程序现在直接安装到“程序文件(x86)”而不考虑架构。例如,由于 SOAPSonar,我在 32 位机器上拥有该目录。
                      【解决方案29】:

                      我用:

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

                      这将获取启动应用程序的路径,以防您将应用程序安装在计算机上的不同位置。此外,您可以只使用一般的 C:\ 路径,因为 99.9% 的计算机都在 C:\ 中安装了 Windows。

                      【讨论】:

                      • 非常糟糕的方法。如果将来这个目录被重命名怎么办? Windows的本地化版本怎么样?在 Windows XP 德语中,“程序文件”称为“程序”。我不确定,但 XP 64 可能因此将其称为“程序 (x86)”。
                      • 我不推荐它,但您可以通过扩展环境变量 %ProgramFiles(x86)% 来解决本地化问题
                      【解决方案30】:

                      我使用以下版本:

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

                      【讨论】:

                      • 由于本地化程序文件夹名称,这不适用于非英语 XP 版本。
                      • 不过64位系统也有这个文件夹哈哈
                      猜你喜欢
                      • 2011-04-06
                      • 2015-05-18
                      • 1970-01-01
                      • 1970-01-01
                      • 2012-10-25
                      • 2011-10-24
                      • 1970-01-01
                      相关资源
                      最近更新 更多