Получение Windows Версия ОС программно

Я пытаюсь получить версию Windows с C# на моей машине Windows 10.

Я всегда получаю эти значения (с C#с++):

майор: 6

минор: 2

, который является ОС Windows 8, соответственно 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.%un", info.dwMajorVersion, info.dwMinorVersion);
}

Windows 10 предполагается с теми:

главные: 10

минор: 0*

  • (когда я беру файл дампа из запущенного процесса, я вижу, что версия ОС этого файла установлена в 10.0)

построено: 10.0.10586.0 (th2_release.151029-1700)

что я пропустила?

6 ответов


поскольку принятый ответ только для C#, вот решение для C++.

он использует RtlGetVersion в ntdll.dll, которая использует ту же структуру, что и GetVersionEx (имя отличается, но элементы одинаковы) и дает вам правильную версию. Поскольку эта функция обычно используется для разработки драйверов, функция объявляется в DDK, а не в SDK. Поэтому я использовал динамическое решение для вызова функции. Обратите внимание, что ntdll.dll загружается и выпускается в каждый вызов. Поэтому, если вам нужна функция чаще, держите библиотеку загруженной.

структура, на которую указывает pOSversion, должна быть инициализирована как для GetVersionEx.

BOOL GetTrueWindowsVersion(OSVERSIONINFOEX* pOSversion)
{
   // Function pointer to driver function
   NTSTATUS (WINAPI *pRtlGetVersion)(
      PRTL_OSVERSIONINFOW lpVersionInformation) = NULL;

   // load the System-DLL
   HINSTANCE hNTdllDll = LoadLibrary("ntdll.dll");

   // successfully loaded?
   if (hNTdllDll != NULL)
   {
      // get the function pointer to RtlGetVersion
      pRtlGetVersion = (NTSTATUS (WINAPI *)(PRTL_OSVERSIONINFOW))
            GetProcAddress (hNTdllDll, "RtlGetVersion");

      // if successfull then read the function
      if (pRtlGetVersion != NULL)
         pRtlGetVersion((PRTL_OSVERSIONINFOW)pOSversion);

      // free the library
      FreeLibrary(hNTdllDll);
   } // if (hNTdllDll != NULL)

   // if function failed, use fallback to old version
   if (pRtlGetVersion == NULL)
      GetVersionEx((OSVERSIONINFO*)pOSversion);

   // always true ...
   return (TRUE);
} // GetTrueWindowsVersion

в моем сценарии мне нужно было мое приложение для захвата информации о компьютере для возможных отчетов об ошибках и статистики.

Я не нашел решения, где манифест приложения пришлось добавить удовлетворительно. большинство предложений, которые я нашел во время поиска в гугле, к сожалению, предложили именно это.

дело в том, что при использовании манифеста каждая версия ОС должна быть добавлена вручную, чтобы эта конкретная версия ОС могла сообщить о себе во время выполнения.

другими словами, это становится условием гонки: пользователь моего приложения может очень хорошо использовать версию моего приложения, которая до используемая ОС. Мне придется обновить приложение тут когда новая версия ОС была запущена Microsoft. Мне также придется заставить пользователей обновить приложение одновременно с обновлением ОС.

другими словами, не очень осуществимо.

после просматривая параметры, я нашел некоторые ссылки (удивительно мало по сравнению с манифестом приложения), которые вместо этого предложили использовать поиск реестра.

мой (порубленные) ComputerInfo класс только WinMajorVersion, WinMinorVersion и 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;
            }
        }
    }
}

вам нужно добавить app.manifest приложения:

enter image description here

enter image description here

затем раскомментируйте следующую строку:

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

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

тот же код для всех ОС от XP до текущего 10.16299, над сценариями не работает должным образом из windows 8

свойство osversion сообщает тот же номер версии (6.2.0.0) для Windows 8 и Windows 8.1 и те же крупные и мелкие версии для Windows 10.

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


вы можете читать из regsirty через код и выполнять определенные действия, которые вы намеревались.

сказать, например:

ключ реестра вы можете найти здесь:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion, а затем найдите "Имя_продукта"

вы можете открыть информацию реестра, предоставив regedit.exe в run (windows+r)

var reg              =Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\WindowsNT\CurrentVersion");

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

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

Вы можете сделать это на C# так же, как C++ answer имеет это

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