web-dev-qa-db-fra.com

Obtenir la version de Windows OS par programme

J'essaie de récupérer la version Windows avec C # sur mon ordinateur Windows 10.

Je reçois toujours ces valeurs (avec C #\C++):

Major: 6 

Mineure: 2

Quel est le système d'exploitation Windows 8, selon MSDN

Code C #:  

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

Code 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 est supposé être avec ceux-ci:

Major: 10

Mineure: 0 *

  • (Lorsque je prends un fichier de vidage du processus en cours, je peux voir que la version du système d'exploitation de ce fichier est définie sur 10.0)

construit par: 10.0.10586.0 (th2_release.151029-1700)

Qu'est-ce que j'oublie ici?

10
Pavel Durov

Comme la réponse acceptée ne concerne que le C #, voici une solution pour le C++.

Il utilise RtlGetVersion dans le fichier ntdll.dll qui utilise la même structure que GetVersionEx (le nom est différent, mais les éléments sont identiques) et vous donne la version correcte. Comme cette fonction est normalement utilisée pour le développement de pilotes, elle est déclarée dans le DDK et non dans le SDK. J'ai donc utilisé une solution dynamique pour appeler la fonction. Veuillez noter que le ntdll.dll est chargé et publié à chaque appel. Donc, si vous avez besoin de la fonction plus souvent, gardez la bibliothèque chargée.

La structure pointée par pOSversion doit être initialisée comme pour 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
0
Peter Thaus

Dans mon scénario, j'avais besoin de mon application pour capturer les informations de l'ordinateur afin de générer des rapports de bogues et des statistiques.

Je n'ai pas trouvé les solutions où un manifeste d'application devait être ajouté de manière satisfaisante. La plupart des suggestions que j'ai trouvées en recherchant cela suggéraient cela, malheureusement.

En réalité, lors de l'utilisation d'un manifeste, chaque version de système d'exploitation doit y être ajoutée manuellement afin que cette version de système d'exploitation puisse se rapporter elle-même au moment de l'exécution.

En d'autres termes, cela devient une condition de concurrence critique: un utilisateur de mon application peut très bien utiliser une version de mon application qui est antérieure à la date d'utilisation du système d'exploitation utilisé. Je devrais mettre à jour l'application immédiatement lorsque Microsoft a lancé une nouvelle version du système d'exploitation. Je devrais également obliger les utilisateurs à mettre à niveau l'application en même temps qu'ils mettent à jour le système d'exploitation.

En d'autres termes, pas très faisable.

Après avoir parcouru les options, j'ai trouvé quelques références (étonnamment peu comparées au manifeste de l'application) suggérant d'utiliser des recherches dans le registre.

Ma classe (variée) ComputerInfo avec uniquement les propriétés WinMajorVersion, WinMinorVersion et IsServer ressemble à ceci:

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

Vous devrez ajouter un app.manifest à votre application:

 enter image description here

 enter image description here

puis décommentez la ligne suivante:

<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
4
Nasreddine
Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentBuildNumber", string.Empty).ToString()

même code pour tous les systèmes d'exploitation de XP jusqu'au 10.16299 actuel, sur les scénarios ne fonctionnant pas correctement à partir de Windows 8

La propriété OSVersion indique le même numéro de version (6.2.0.0) pour Windows 8 et Windows 8.1 et les mêmes numéros de version majeure et mineure pour Windows 10.

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

3
michael

Vous pouvez lire de regsirty à travers le code et faire des actions spécifiques ce que vous vouliez.

Dites par exemple:

La clé de registre que vous pouvez trouver ici:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion puis recherchez "NomProduit"

Vous pouvez ouvrir les informations de registre en donnant regedit.exe en exécution (windows + r)

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

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

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

Vous pouvez le faire en C # de la même manière que la réponse 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.
}
0
Richard - MSFT