How to detect Windows 64-bit platform with .NET?

前端 未结 29 2720
野性不改
野性不改 2020-11-22 04:53

In a .NET 2.0 C# application I use the following code to detect the operating system platform:

string os_platform = System.Environment.OSVersion.Platform.ToS         


        
相关标签:
29条回答
  • 2020-11-22 05:06

    I need to do this, but I also need to be able as an admin do it remotely, either case this seems to work quite nicely for me:

        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;
            }
        }
    
    0 讨论(0)
  • 2020-11-22 05:07

    Microsoft has put a code sample for this:

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

    It looks like this:

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

    There is a WMI version available as well (for testing remote machines).

    0 讨论(0)
  • 2020-11-22 05:07

    You can also check for the PROCESSOR_ARCHITECTURE environment variable.

    It either doesn't exist or is set to "x86" on 32-bit Windows.

    private int GetOSArchitecture()
    {
        string pa = 
            Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE");
        return ((String.IsNullOrEmpty(pa) || 
                 String.Compare(pa, 0, "x86", 0, 3, true) == 0) ? 32 : 64);
    }
    
    0 讨论(0)
  • 2020-11-22 05:08

    UPDATE: As Joel Coehoorn and others suggest, starting at .NET Framework 4.0, you can just check Environment.Is64BitOperatingSystem.


    IntPtr.Size won't return the correct value if running in 32-bit .NET Framework 2.0 on 64-bit Windows (it would return 32-bit).

    As Microsoft's Raymond Chen describes, you have to first check if running in a 64-bit process (I think in .NET you can do so by checking IntPtr.Size), and if you are running in a 32-bit process, you still have to call the Win API function IsWow64Process. If this returns true, you are running in a 32-bit process on 64-bit Windows.

    Microsoft's Raymond Chen: How to detect programmatically whether you are running on 64-bit Windows

    My solution:

    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;
        }
    }
    
    0 讨论(0)
  • 2020-11-22 05:09

    Use this to get the installed Windows architecture:

    string getOSArchitecture()
    {
        string architectureStr;
        if (Directory.Exists(Environment.GetFolderPath(
                               Environment.SpecialFolder.ProgramFilesX86))) {
            architectureStr ="64-bit";
        }
        else {
            architectureStr = "32-bit";
        }
        return architectureStr;
    }
    
    0 讨论(0)
  • 2020-11-22 05:11

    This is just an implementation of what's suggested above by Bruno Lopez, but works on Win2k + all WinXP service packs. Just figured I'd post it so other people didn't have roll it by hand. (would have posted as a comment, but I'm a new user!)

    [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;
    }
    
    0 讨论(0)
提交回复
热议问题