以编程方式获取Windows操作系统版本

时间:2016-06-08 10:58:36

标签: c# windows operating-system version windowsversion

我正在尝试在Windows 10计算机上使用C#获取Windows版本。

我总是得到这些值(使用C#\ C ++):

  

专业:6

     

轻微:2

哪个是Windows 8操作系统,accordingly to MSDN

C#代码:

var major = OperatingSystem.Version.Major
var minor  = OperatingSystem.Version.Minor

C ++代码

void print_os_info()
{
    //http://stackoverflow.com/questions/1963992/check-windows-version
    OSVERSIONINFOW info;
    ZeroMemory(&info, sizeof(OSVERSIONINFOW));
    info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);

    LPOSVERSIONINFOW lp_info = &info;
    GetVersionEx(lp_info);

    printf("Windows version: %u.%u\n", info.dwMajorVersion, info.dwMinorVersion);
}

Windows 10假设与那些:

  

专业:10

     

轻微:0 *

  • (当我从运行进程中获取转储文件时,我可以看到该文件的操作系统版本设置为10.0)
  

建立者:10.0.10586.0(th2_release.151029-1700)

我在这里缺少什么?

6 个答案:

答案 0 :(得分:14)

在我的场景中,我需要我的应用程序来捕获计算机信息,以获取可能的错误报告和统计信息。

我没有找到必须添加应用程序清单的解决方案。我在谷歌搜索时发现的大多数建议都表明,不幸的是。

事实是,当使用清单时,必须手动添加每个操作系统版本,以便该特定操作系统版本能够在运行时报告自己。

换句话说,这会成为一种竞争条件:我的应用程序的用户可能正在使用我的应用程序版本预先正在使用的操作系统。当Microsoft推出新操作系统版本时,我必须立即升级应用程序 。我还必须强制用户在更新操作系统的同时升级应用程序。

换句话说,不太可行。

在浏览选项后,我发现了一些引用(与应用清单相比很少见)而是建议使用注册表查找。

仅包含ComputerInfoWinMajorVersionWinMinorVersion属性的我(已删除)IsServer课程如下所示:

using Microsoft.Win32;

namespace Inspection
{
    /// <summary>
    /// Static class that adds convenient methods for getting information on the running computers basic hardware and os setup.
    /// </summary>
    public static class ComputerInfo
    {
        /// <summary>
        ///     Returns the Windows major version number for this computer.
        /// </summary>
        public static uint WinMajorVersion
        {
            get
            {
                dynamic major;
                // The 'CurrentMajorVersionNumber' string value in the CurrentVersion key is new for Windows 10, 
                // and will most likely (hopefully) be there for some time before MS decides to change this - again...
                if (TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentMajorVersionNumber", out major))
                {
                    return (uint) major;
                }

                // When the 'CurrentMajorVersionNumber' value is not present we fallback to reading the previous key used for this: 'CurrentVersion'
                dynamic version;
                if (!TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentVersion", out version))
                    return 0;

                var versionParts = ((string) version).Split('.');
                if (versionParts.Length != 2) return 0;
                uint majorAsUInt;
                return uint.TryParse(versionParts[0], out majorAsUInt) ? majorAsUInt : 0;
            }
        }

        /// <summary>
        ///     Returns the Windows minor version number for this computer.
        /// </summary>
        public static uint WinMinorVersion
        {
            get
            {
                dynamic minor;
                // The 'CurrentMinorVersionNumber' string value in the CurrentVersion key is new for Windows 10, 
                // and will most likely (hopefully) be there for some time before MS decides to change this - again...
                if (TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentMinorVersionNumber",
                    out minor))
                {
                    return (uint) minor;
                }

                // When the 'CurrentMinorVersionNumber' value is not present we fallback to reading the previous key used for this: 'CurrentVersion'
                dynamic version;
                if (!TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentVersion", out version))
                    return 0;

                var versionParts = ((string) version).Split('.');
                if (versionParts.Length != 2) return 0;
                uint minorAsUInt;
                return uint.TryParse(versionParts[1], out minorAsUInt) ? minorAsUInt : 0;
            }
        }

        /// <summary>
        ///     Returns whether or not the current computer is a server or not.
        /// </summary>
        public static uint IsServer
        {
            get
            {
                dynamic installationType;
                if (TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "InstallationType",
                    out installationType))
                {
                    return (uint) (installationType.Equals("Client") ? 0 : 1);
                }

                return 0;
            }
        }

        private static bool TryGetRegistryKey(string path, string key, out dynamic value)
        {
            value = null;
            try
            {
                using(var rk = Registry.LocalMachine.OpenSubKey(path))
                {
                    if (rk == null) return false;
                    value = rk.GetValue(key);
                    return value != null;
                }
            }
            catch
            {
                return false;
            }
        }
    }
}

答案 1 :(得分:4)

您需要在应用中添加app.manifest

enter image description here

enter image description here

然后取消注释以下行:

<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />

答案 2 :(得分:3)

Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentBuildNumber", string.Empty).ToString()

所有操作系统的代码从XP到当前的10.16299, 场景不能正常工作从Windows 8

  

OSVersion属性报告Windows 8和Windows 8.1的相同版本号(6.2.0.0)以及Windows 10的相同主版本号和次版本号。

https://msdn.microsoft.com/library/system.environment.osversion.aspx

答案 3 :(得分:1)

您可以通过代码阅读regsirty并按照您的意图执行特定操作。

说出来:

您可以在此处找到注册表项:

HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion然后查找“ProductName”

您可以通过在运行中提供regedit.exe(windows + r)

来打开注册表信息
var reg              =Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\WindowsNT\CurrentVersion");

        string productName = (string)reg.GetValue("ProductName");

        if (productName.StartsWith("Windows 10"))
        {
        }
        else
        {
        }

答案 4 :(得分:0)

由于接受的答案仅适用于C#,因此这是C ++的解决方案。

它使用ntdll.dll中的RtlGetVersion,它使用与GetVersionEx相同的结构(名称不同,但元素相同)并为您提供正确的版本。 由于此函数通常用于驱动程序开发,因此该函数在DDK中声明,而不是在SDK中声明。所以我使用动态解决方案来调用该函数。 请注意,每次调用都会加载并释放ntdll.dll。因此,如果您更频繁地需要该功能,请保持库的加载。

pOSversion指向的结构必须像GetVersionEx一样初始化。

Name

答案 5 :(得分:0)

您可以在C#中执行此操作,就像C ++的答案一样

[SecurityCritical]
[DllImport("ntdll.dll", SetLastError = true)]
internal static extern bool RtlGetVersion(ref OSVERSIONINFOEX versionInfo);
[StructLayout(LayoutKind.Sequential)]
internal struct OSVERSIONINFOEX
{
    // The OSVersionInfoSize field must be set to Marshal.SizeOf(typeof(OSVERSIONINFOEX))
    internal int OSVersionInfoSize;
    internal int MajorVersion;
    internal int MinorVersion;
    internal int BuildNumber;
    internal int PlatformId;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
    internal string CSDVersion;
    internal ushort ServicePackMajor;
    internal ushort ServicePackMinor;
    internal short SuiteMask;
    internal byte ProductType;
    internal byte Reserved;
}

...

var osVersionInfo = new OSVERSIONINFOEX { OSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFOEX)) };
if (!RtlGetVersion(ref osVersionInfo))
{
  // TODO: Error handling, call GetVersionEx, etc.
}