How can I detect the Windows OS versio开发者_运维知识库ns in .NET?
What code can I use?
System.Environment.OSVersion
has the information you need for distinguishing most Windows OS major releases, but not all. It consists of three components which map to the following Windows versions:
+------------------------------------------------------------------------------+
| | PlatformID | Major version | Minor version |
+------------------------------------------------------------------------------+
| Windows 95 | Win32Windows | 4 | 0 |
| Windows 98 | Win32Windows | 4 | 10 |
| Windows Me | Win32Windows | 4 | 90 |
| Windows NT 4.0 | Win32NT | 4 | 0 |
| Windows 2000 | Win32NT | 5 | 0 |
| Windows XP | Win32NT | 5 | 1 |
| Windows 2003 | Win32NT | 5 | 2 |
| Windows Vista | Win32NT | 6 | 0 |
| Windows 2008 | Win32NT | 6 | 0 |
| Windows 7 | Win32NT | 6 | 1 |
| Windows 2008 R2 | Win32NT | 6 | 1 |
| Windows 8 | Win32NT | 6 | 2 |
| Windows 8.1 | Win32NT | 6 | 3 |
+------------------------------------------------------------------------------+
| Windows 10 | Win32NT | 10 | 0 |
+------------------------------------------------------------------------------+
For a library that allows you to get a more complete view of the exact release of Windows that the current execution environment is running in, check out this library.
Important note: if your executable assembly manifest doesn't explicitly state that your exe assembly is compatible with Windows 8.1 and Windows 10.0, System.Environment.OSVersion
will return Windows 8 version, which is 6.2, instead of 6.3 and 10.0! Source: here.
Update: In .NET 5.0 and later, System.Environment.OSVersion
always returns the actual OS version. For more information, see Environment.OSVersion returns the correct operating system version.
I used this when I had to determine various Microsoft Operating System versions:
string getOSInfo()
{
//Get Operating system information.
OperatingSystem os = Environment.OSVersion;
//Get version information about the os.
Version vs = os.Version;
//Variable to hold our return value
string operatingSystem = "";
if (os.Platform == PlatformID.Win32Windows)
{
//This is a pre-NT version of Windows
switch (vs.Minor)
{
case 0:
operatingSystem = "95";
break;
case 10:
if (vs.Revision.ToString() == "2222A")
operatingSystem = "98SE";
else
operatingSystem = "98";
break;
case 90:
operatingSystem = "Me";
break;
default:
break;
}
}
else if (os.Platform == PlatformID.Win32NT)
{
switch (vs.Major)
{
case 3:
operatingSystem = "NT 3.51";
break;
case 4:
operatingSystem = "NT 4.0";
break;
case 5:
if (vs.Minor == 0)
operatingSystem = "2000";
else
operatingSystem = "XP";
break;
case 6:
if (vs.Minor == 0)
operatingSystem = "Vista";
else if (vs.Minor == 1)
operatingSystem = "7";
else if (vs.Minor == 2)
operatingSystem = "8";
else
operatingSystem = "8.1";
break;
case 10:
operatingSystem = "10";
break;
default:
break;
}
}
//Make sure we actually got something in our OS check
//We don't want to just return " Service Pack 2" or " 32-bit"
//That information is useless without the OS version.
if (operatingSystem != "")
{
//Got something. Let's prepend "Windows" and get more info.
operatingSystem = "Windows " + operatingSystem;
//See if there's a service pack installed.
if (os.ServicePack != "")
{
//Append it to the OS name. i.e. "Windows XP Service Pack 3"
operatingSystem += " " + os.ServicePack;
}
//Append the OS architecture. i.e. "Windows XP Service Pack 3 32-bit"
//operatingSystem += " " + getOSArchitecture().ToString() + "-bit";
}
//Return the information we've gathered.
return operatingSystem;
}
Source: here
I use the ManagementObjectSearcher
of namespace System.Management
Example:
string r = "";
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem"))
{
ManagementObjectCollection information = searcher.Get();
if (information != null)
{
foreach (ManagementObject obj in information)
{
r = obj["Caption"].ToString() + " - " + obj["OSArchitecture"].ToString();
}
}
r = r.Replace("NT 5.1.2600", "XP");
r = r.Replace("NT 5.2.3790", "Server 2003");
MessageBox.Show(r);
}
Do not forget to add the reference to the Assembly
System.Management.dll
and put the using:using System.Management;
Result:
Documentation
This is a relatively old question but I've recently had to solve this problem and didn't see my solution posted anywhere.
The easiest (and simplest way in my opinion) is to just use a pinvoke call to RtlGetVersion
[DllImport("ntdll.dll", SetLastError = true)]
internal static extern uint RtlGetVersion(out Structures.OsVersionInfo versionInformation); // return type should be the NtStatus enum
[StructLayout(LayoutKind.Sequential)]
internal struct OsVersionInfo
{
private readonly uint OsVersionInfoSize;
internal readonly uint MajorVersion;
internal readonly uint MinorVersion;
private readonly uint BuildNumber;
private readonly uint PlatformId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
private readonly string CSDVersion;
}
Where Major and Minor version numbers in this struct correspond to the values in the table of the accepted answer.
This returns the correct Windows version number unlike the deprecated GetVersion & GetVersionEx functions from kernel32
You can use this helper class;
using System;
using System.Runtime.InteropServices;
/// <summary>
/// Provides detailed information about the host operating system.
/// </summary>
public static class OSInfo
{
#region BITS
/// <summary>
/// Determines if the current application is 32 or 64-bit.
/// </summary>
public static int Bits
{
get
{
return IntPtr.Size * 8;
}
}
#endregion BITS
#region EDITION
private static string s_Edition;
/// <summary>
/// Gets the edition of the operating system running on this computer.
/// </summary>
public static string Edition
{
get
{
if (s_Edition != null)
return s_Edition; //***** RETURN *****//
string edition = String.Empty;
OperatingSystem osVersion = Environment.OSVersion;
OSVERSIONINFOEX osVersionInfo = new OSVERSIONINFOEX();
osVersionInfo.dwOSVersionInfoSize = Marshal.SizeOf( typeof( OSVERSIONINFOEX ) );
if (GetVersionEx( ref osVersionInfo ))
{
int majorVersion = osVersion.Version.Major;
int minorVersion = osVersion.Version.Minor;
byte productType = osVersionInfo.wProductType;
short suiteMask = osVersionInfo.wSuiteMask;
#region VERSION 4
if (majorVersion == 4)
{
if (productType == VER_NT_WORKSTATION)
{
// Windows NT 4.0 Workstation
edition = "Workstation";
}
else if (productType == VER_NT_SERVER)
{
if ((suiteMask & VER_SUITE_ENTERPRISE) != 0)
{
// Windows NT 4.0 Server Enterprise
edition = "Enterprise Server";
}
else
{
// Windows NT 4.0 Server
edition = "Standard Server";
}
}
}
#endregion VERSION 4
#region VERSION 5
else if (majorVersion == 5)
{
if (productType == VER_NT_WORKSTATION)
{
if ((suiteMask & VER_SUITE_PERSONAL) != 0)
{
// Windows XP Home Edition
edition = "Home";
}
else
{
// Windows XP / Windows 2000 Professional
edition = "Professional";
}
}
else if (productType == VER_NT_SERVER)
{
if (minorVersion == 0)
{
if ((suiteMask & VER_SUITE_DATACENTER) != 0)
{
// Windows 2000 Datacenter Server
edition = "Datacenter Server";
}
else if ((suiteMask & VER_SUITE_ENTERPRISE) != 0)
{
// Windows 2000 Advanced Server
edition = "Advanced Server";
}
else
{
// Windows 2000 Server
edition = "Server";
}
}
else
{
if ((suiteMask & VER_SUITE_DATACENTER) != 0)
{
// Windows Server 2003 Datacenter Edition
edition = "Datacenter";
}
else if ((suiteMask & VER_SUITE_ENTERPRISE) != 0)
{
// Windows Server 2003 Enterprise Edition
edition = "Enterprise";
}
else if ((suiteMask & VER_SUITE_BLADE) != 0)
{
// Windows Server 2003 Web Edition
edition = "Web Edition";
}
else
{
// Windows Server 2003 Standard Edition
edition = "Standard";
}
}
}
}
#endregion VERSION 5
#region VERSION 6
else if (majorVersion == 6)
{
int ed;
if (GetProductInfo( majorVersion, minorVersion,
osVersionInfo.wServicePackMajor, osVersionInfo.wServicePackMinor,
out ed ))
{
switch (ed)
{
case PRODUCT_BUSINESS:
edition = "Business";
break;
case PRODUCT_BUSINESS_N:
edition = "Business N";
break;
case PRODUCT_CLUSTER_SERVER:
edition = "HPC Edition";
break;
case PRODUCT_DATACENTER_SERVER:
edition = "Datacenter Server";
break;
case PRODUCT_DATACENTER_SERVER_CORE:
edition = "Datacenter Server (core installation)";
break;
case PRODUCT_ENTERPRISE:
edition = "Enterprise";
break;
case PRODUCT_ENTERPRISE_N:
edition = "Enterprise N";
break;
case PRODUCT_ENTERPRISE_SERVER:
edition = "Enterprise Server";
break;
case PRODUCT_ENTERPRISE_SERVER_CORE:
edition = "Enterprise Server (core installation)";
break;
case PRODUCT_ENTERPRISE_SERVER_CORE_V:
edition = "Enterprise Server without Hyper-V (core installation)";
break;
case PRODUCT_ENTERPRISE_SERVER_IA64:
edition = "Enterprise Server for Itanium-based Systems";
break;
case PRODUCT_ENTERPRISE_SERVER_V:
edition = "Enterprise Server without Hyper-V";
break;
case PRODUCT_HOME_BASIC:
edition = "Home Basic";
break;
case PRODUCT_HOME_BASIC_N:
edition = "Home Basic N";
break;
case PRODUCT_HOME_PREMIUM:
edition = "Home Premium";
break;
case PRODUCT_HOME_PREMIUM_N:
edition = "Home Premium N";
break;
case PRODUCT_HYPERV:
edition = "Microsoft Hyper-V Server";
break;
case PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT:
edition = "Windows Essential Business Management Server";
break;
case PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING:
edition = "Windows Essential Business Messaging Server";
break;
case PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY:
edition = "Windows Essential Business Security Server";
break;
case PRODUCT_SERVER_FOR_SMALLBUSINESS:
edition = "Windows Essential Server Solutions";
break;
case PRODUCT_SERVER_FOR_SMALLBUSINESS_V:
edition = "Windows Essential Server Solutions without Hyper-V";
break;
case PRODUCT_SMALLBUSINESS_SERVER:
edition = "Windows Small Business Server";
break;
case PRODUCT_STANDARD_SERVER:
edition = "Standard Server";
break;
case PRODUCT_STANDARD_SERVER_CORE:
edition = "Standard Server (core installation)";
break;
case PRODUCT_STANDARD_SERVER_CORE_V:
edition = "Standard Server without Hyper-V (core installation)";
break;
case PRODUCT_STANDARD_SERVER_V:
edition = "Standard Server without Hyper-V";
break;
case PRODUCT_STARTER:
edition = "Starter";
break;
case PRODUCT_STORAGE_ENTERPRISE_SERVER:
edition = "Enterprise Storage Server";
break;
case PRODUCT_STORAGE_EXPRESS_SERVER:
edition = "Express Storage Server";
break;
case PRODUCT_STORAGE_STANDARD_SERVER:
edition = "Standard Storage Server";
break;
case PRODUCT_STORAGE_WORKGROUP_SERVER:
edition = "Workgroup Storage Server";
break;
case PRODUCT_UNDEFINED:
edition = "Unknown product";
break;
case PRODUCT_ULTIMATE:
edition = "Ultimate";
break;
case PRODUCT_ULTIMATE_N:
edition = "Ultimate N";
break;
case PRODUCT_WEB_SERVER:
edition = "Web Server";
break;
case PRODUCT_WEB_SERVER_CORE:
edition = "Web Server (core installation)";
break;
}
}
}
#endregion VERSION 6
}
s_Edition = edition;
return edition;
}
}
#endregion EDITION
#region NAME
private static string s_Name;
/// <summary>
/// Gets the name of the operating system running on this computer.
/// </summary>
public static string Name
{
get
{
if (s_Name != null)
return s_Name; //***** RETURN *****//
string name = "unknown";
OperatingSystem osVersion = Environment.OSVersion;
OSVERSIONINFOEX osVersionInfo = new OSVERSIONINFOEX();
osVersionInfo.dwOSVersionInfoSize = Marshal.SizeOf( typeof( OSVERSIONINFOEX ) );
if (GetVersionEx( ref osVersionInfo ))
{
int majorVersion = osVersion.Version.Major;
int minorVersion = osVersion.Version.Minor;
switch (osVersion.Platform)
{
case PlatformID.Win32Windows:
{
if (majorVersion == 4)
{
string csdVersion = osVersionInfo.szCSDVersion;
switch (minorVersion)
{
case 0:
if (csdVersion == "B" || csdVersion == "C")
name = "Windows 95 OSR2";
else
name = "Windows 95";
break;
case 10:
if (csdVersion == "A")
name = "Windows 98 Second Edition";
else
name = "Windows 98";
break;
case 90:
name = "Windows Me";
break;
}
}
break;
}
case PlatformID.Win32NT:
{
byte productType = osVersionInfo.wProductType;
switch (majorVersion)
{
case 3:
name = "Windows NT 3.51";
break;
case 4:
switch (productType)
{
case 1:
name = "Windows NT 4.0";
break;
case 3:
name = "Windows NT 4.0 Server";
break;
}
break;
case 5:
switch (minorVersion)
{
case 0:
name = "Windows 2000";
break;
case 1:
name = "Windows XP";
break;
case 2:
name = "Windows Server 2003";
break;
}
break;
case 6:
switch (productType)
{
case 1:
name = "Windows Vista";
break;
case 3:
name = "Windows Server 2008";
break;
}
break;
}
break;
}
}
}
s_Name = name;
return name;
}
}
#endregion NAME
#region PINVOKE
#region GET
#region PRODUCT INFO
[DllImport( "Kernel32.dll" )]
internal static extern bool GetProductInfo(
int osMajorVersion,
int osMinorVersion,
int spMajorVersion,
int spMinorVersion,
out int edition );
#endregion PRODUCT INFO
#region VERSION
[DllImport( "kernel32.dll" )]
private static extern bool GetVersionEx( ref OSVERSIONINFOEX osVersionInfo );
#endregion VERSION
#endregion GET
#region OSVERSIONINFOEX
[StructLayout( LayoutKind.Sequential )]
private struct OSVERSIONINFOEX
{
public int dwOSVersionInfoSize;
public int dwMajorVersion;
public int dwMinorVersion;
public int dwBuildNumber;
public int dwPlatformId;
[MarshalAs( UnmanagedType.ByValTStr, SizeConst = 128 )]
public string szCSDVersion;
public short wServicePackMajor;
public short wServicePackMinor;
public short wSuiteMask;
public byte wProductType;
public byte wReserved;
}
#endregion OSVERSIONINFOEX
#region PRODUCT
private const int PRODUCT_UNDEFINED = 0x00000000;
private const int PRODUCT_ULTIMATE = 0x00000001;
private const int PRODUCT_HOME_BASIC = 0x00000002;
private const int PRODUCT_HOME_PREMIUM = 0x00000003;
private const int PRODUCT_ENTERPRISE = 0x00000004;
private const int PRODUCT_HOME_BASIC_N = 0x00000005;
private const int PRODUCT_BUSINESS = 0x00000006;
private const int PRODUCT_STANDARD_SERVER = 0x00000007;
private const int PRODUCT_DATACENTER_SERVER = 0x00000008;
private const int PRODUCT_SMALLBUSINESS_SERVER = 0x00000009;
private const int PRODUCT_ENTERPRISE_SERVER = 0x0000000A;
private const int PRODUCT_STARTER = 0x0000000B;
private const int PRODUCT_DATACENTER_SERVER_CORE = 0x0000000C;
private const int PRODUCT_STANDARD_SERVER_CORE = 0x0000000D;
private const int PRODUCT_ENTERPRISE_SERVER_CORE = 0x0000000E;
private const int PRODUCT_ENTERPRISE_SERVER_IA64 = 0x0000000F;
private const int PRODUCT_BUSINESS_N = 0x00000010;
private const int PRODUCT_WEB_SERVER = 0x00000011;
private const int PRODUCT_CLUSTER_SERVER = 0x00000012;
private const int PRODUCT_HOME_SERVER = 0x00000013;
private const int PRODUCT_STORAGE_EXPRESS_SERVER = 0x00000014;
private const int PRODUCT_STORAGE_STANDARD_SERVER = 0x00000015;
private const int PRODUCT_STORAGE_WORKGROUP_SERVER = 0x00000016;
private const int PRODUCT_STORAGE_ENTERPRISE_SERVER = 0x00000017;
private const int PRODUCT_SERVER_FOR_SMALLBUSINESS = 0x00000018;
private const int PRODUCT_SMALLBUSINESS_SERVER_PREMIUM = 0x00000019;
private const int PRODUCT_HOME_PREMIUM_N = 0x0000001A;
private const int PRODUCT_ENTERPRISE_N = 0x0000001B;
private const int PRODUCT_ULTIMATE_N = 0x0000001C;
private const int PRODUCT_WEB_SERVER_CORE = 0x0000001D;
private const int PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT = 0x0000001E;
private const int PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY = 0x0000001F;
private const int PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING = 0x00000020;
private const int PRODUCT_SERVER_FOR_SMALLBUSINESS_V = 0x00000023;
private const int PRODUCT_STANDARD_SERVER_V = 0x00000024;
private const int PRODUCT_ENTERPRISE_SERVER_V = 0x00000026;
private const int PRODUCT_STANDARD_SERVER_CORE_V = 0x00000028;
private const int PRODUCT_ENTERPRISE_SERVER_CORE_V = 0x00000029;
private const int PRODUCT_HYPERV = 0x0000002A;
#endregion PRODUCT
#region VERSIONS
private const int VER_NT_WORKSTATION = 1;
private const int VER_NT_DOMAIN_CONTROLLER = 2;
private const int VER_NT_SERVER = 3;
private const int VER_SUITE_SMALLBUSINESS = 1;
private const int VER_SUITE_ENTERPRISE = 2;
private const int VER_SUITE_TERMINAL = 16;
private const int VER_SUITE_DATACENTER = 128;
private const int VER_SUITE_SINGLEUSERTS = 256;
private const int VER_SUITE_PERSONAL = 512;
private const int VER_SUITE_BLADE = 1024;
#endregion VERSIONS
#endregion PINVOKE
#region SERVICE PACK
/// <summary>
/// Gets the service pack information of the operating system running on this computer.
/// </summary>
public static string ServicePack
{
get
{
string servicePack = String.Empty;
OSVERSIONINFOEX osVersionInfo = new OSVERSIONINFOEX();
osVersionInfo.dwOSVersionInfoSize = Marshal.SizeOf( typeof( OSVERSIONINFOEX ) );
if (GetVersionEx( ref osVersionInfo ))
{
servicePack = osVersionInfo.szCSDVersion;
}
return servicePack;
}
}
#endregion SERVICE PACK
#region VERSION
#region BUILD
/// <summary>
/// Gets the build version number of the operating system running on this computer.
/// </summary>
public static int BuildVersion
{
get
{
return Environment.OSVersion.Version.Build;
}
}
#endregion BUILD
#region FULL
#region STRING
/// <summary>
/// Gets the full version string of the operating system running on this computer.
/// </summary>
public static string VersionString
{
get
{
return Environment.OSVersion.Version.ToString();
}
}
#endregion STRING
#region VERSION
/// <summary>
/// Gets the full version of the operating system running on this computer.
/// </summary>
public static Version Version
{
get
{
return Environment.OSVersion.Version;
}
}
#endregion VERSION
#endregion FULL
#region MAJOR
/// <summary>
/// Gets the major version number of the operating system running on this computer.
/// </summary>
public static int MajorVersion
{
get
{
return Environment.OSVersion.Version.Major;
}
}
#endregion MAJOR
#region MINOR
/// <summary>
/// Gets the minor version number of the operating system running on this computer.
/// </summary>
public static int MinorVersion
{
get
{
return Environment.OSVersion.Version.Minor;
}
}
#endregion MINOR
#region REVISION
/// <summary>
/// Gets the revision version number of the operating system running on this computer.
/// </summary>
public static int RevisionVersion
{
get
{
return Environment.OSVersion.Version.Revision;
}
}
#endregion REVISION
#endregion VERSION
}
Sample code is here:
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 );
I was found at this address : http://www.csharp411.com/wp-content/uploads/2009/01/OSInfo.cs
Like R. Bemrose suggested, if you are doing Windows 7 specific features, you should look at the Windows® API Code Pack for Microsoft® .NET Framework.
It contains a CoreHelpers
class that let you determine the OS you are currently on (XP and above only, its a requirement for .NET nowaday)
It also provide multiple helper methods. For example, suppose that you want to use the jump list of Windows 7, there is a class TaskbarManager
that provide a property called IsPlatformSupported
and it will return true if you are on Windows 7 and above.
Via Environment.OSVersion
which "Gets an System.OperatingSystem object that contains the current platform identifier and version number."
.NET 5
Starting in .NET 5, Environment.OSVersion
returns the actual version of the operating system for Windows and macOS.
var version = Environment.OSVersion;
Console.WriteLine(version);
// Microsoft Windows NT 10.0.19044.0
https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/5.0/environment-osversion-returns-correct-version
Older versions of dotnet:
To make sure you get the right version using Environment.OSVersion
you should add an app.manifest
using Visual Studio and then un-comment the following supportedOS
tags:
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- A list of the Windows versions that this application has been tested on
and is designed to work with. Uncomment the appropriate elements
and Windows will automatically select the most compatible environment. -->
<!-- Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
Then you can use the Environment.OSVersion
like so:
var version = Environment.OSVersion;
Console.WriteLine(version);
// Before: Microsoft Windows NT 6.2.9200.0
// After: Microsoft Windows NT 10.0.19044.0
For instance in my machine (Windows 10.0 Build 19044
) without the manifest file, the result would be 6.2.9200.0
which is incorrect.
By adding the app.manifest
file and un-commenting those tags I will get the right version number which is 10.0.19044.0
.
Alternative solution
If you don't like adding app.manifest
to your project, you can use OSDescription
which is available on .NET Framework 4.7.1+ and .NET Core 1.x+.
// using System.Runtime.InteropServices;
string description = RuntimeInformation.OSDescription;
You can read more about it and supported platforms here.
These all seem like very complicated answers for a very simple function:
public bool IsWindows7
{
get
{
return (Environment.OSVersion.Version.Major == 6 &
Environment.OSVersion.Version.Minor == 1);
}
}
- Add reference to
Microsoft.VisualBasic
. - Include namespace
using Microsoft.VisualBasic.Devices
; - Use
new ComputerInfo().OSFullName
The return value is "Microsoft Windows 10 Enterprise"
Detect OS Version:
public static string OS_Name()
{
return (string)(from x in new ManagementObjectSearcher(
"SELECT Caption FROM Win32_OperatingSystem").Get().Cast<ManagementObject>()
select x.GetPropertyValue("Caption")).FirstOrDefault();
}
This question goes back to the Windows XP days and both question and answers have been edited over the years.
The following code works using the .NET Framework and should detect all the versions of Windows 10.
Based on this question and answer - ( How to check windows version in C# on .NET 5.0 console app )
using System;
using Microsoft.Win32;
namespace WindowsVersion
{
class Version
{
static void Main(string[] args)
{
string HKLMWinNTCurrent = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion";
string osName = Registry.GetValue(HKLMWinNTCurrent, "productName", "").ToString();
string osRelease = Registry.GetValue(HKLMWinNTCurrent, "ReleaseId", "").ToString();
string osVersion = Environment.OSVersion.Version.ToString();
string osType = Environment.Is64BitOperatingSystem ? "64-bit" : "32-bit";
string osBuild = Registry.GetValue(HKLMWinNTCurrent, "CurrentBuildNumber", "").ToString();
string osUBR = Registry.GetValue(HKLMWinNTCurrent, "UBR", "").ToString();
Console.WriteLine("OS Name:" + osName);
Console.WriteLine("OS Release:" + osRelease);
Console.WriteLine("OS Version:" + osVersion);
Console.WriteLine("OS Type:" + osType);
Console.WriteLine("OS Build:" + osBuild);
Console.WriteLine("OS UBR:" + osUBR);
Console.WriteLine("Press any key to exit.");
Console.ReadLine();
}
}
}
I have tested it on my computer and the result is as follows.
See this Wikipedia article for the list of versions of Windows 10
https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions
Update for Windows 11
According to this link there is currently nowhere in the registry where the Windows product name is held.
https://learn.microsoft.com/en-us/answers/questions/555857/windows-11-product-name-in-registry.html
As a workaround use the following code fragment -
if (osBuild == "22000")
{
osFullName = "Windows 11";
}
On my computer it reports both Windows 10 and Windows 11.
One way:
public string GetOSVersion()
{
int _MajorVersion = Environment.OSVersion.Version.Major;
switch (_MajorVersion) {
case 5:
return "Windows XP";
case 6:
switch (Environment.OSVersion.Version.Minor) {
case 0:
return "Windows Vista";
case 1:
return "Windows 7";
default:
return "Windows Vista & above";
}
break;
default:
return "Unknown";
}
}
Then simply do wrap a select case around the function.
The above answers would give me Major
version 6
on Windows 10.
The solution that I have found to work without adding extra VB libraries was following:
var versionString = (string)Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows NT\\CurrentVersion")?.GetValue("productName");
I wouldn't consider this the best way to get the version, but the upside this is oneliner no extra libraries, and in my case checking if it contains "10"
was good enough.
How about using a Registry to get the name.
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion" has a value ProductName since Windows XP.
[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;
}
private static string HKLM_GetString(string key, string value)
{
try
{
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(key);
return registryKey?.GetValue(value).ToString() ?? String.Empty;
}
catch
{
return String.Empty;
}
}
public static string GetWindowsVersion()
{
string osArchitecture;
try
{
osArchitecture = Is64BitOperatingSystem() ? "64-bit" : "32-bit";
}
catch (Exception)
{
osArchitecture = "32/64-bit (Undetermined)";
}
string productName = HKLM_GetString(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "ProductName");
string csdVersion = HKLM_GetString(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CSDVersion");
string currentBuild = HKLM_GetString(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentBuild");
if (!string.IsNullOrEmpty(productName))
{
return
$"{productName}{(!string.IsNullOrEmpty(csdVersion) ? " " + csdVersion : String.Empty)} {osArchitecture} (OS Build {currentBuild})";
}
return String.Empty;
}
If you are using .NET Framework 4.0 or above. You can remove the Is64BitOperatingSystem() method and use Environment.Is64BitOperatingSystem.
Reading the WinAPI documentation, I've generated a static class that should properly return the name of the OS version. I added some comments from the WinAPI and links to the documentation.
public static class OsVersionHelper
{
public static string GetWindowsVersion()
{
try
{
RtlGetVersion(out OuVersionInfoEXA versionInfo);
return versionInfo.GetOsVersionInfoToOsName();
}
catch (Exception ex)
{
Repl.WriteLine(ex.ToString(), ConsoleColor.White, ConsoleColor.Red);
return string.Empty;
}
}
/// <summary>
/// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlgetversion
/// </summary>
/// <param name="versionInformation">Pointer to either a RTL_OSVERSIONINFOW structure or a RTL_OSVERSIONINFOEXW structure that contains the version information about the currently running operating system. A caller specifies which input structure is used by setting the dwOSVersionInfoSize member of the structure to the size in bytes of the structure that is used.</param>
/// <returns>RtlGetVersion returns STATUS_SUCCESS.</returns>
[DllImport("ntdll.dll", SetLastError = true)]
internal static extern uint RtlGetVersion(out OuVersionInfoEXA versionInformation); // return type should be the NtStatus enum
/// <summary>
/// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_osversioninfoexw
/// </summary>
///
/// <remarks>
/// Operating system Version number dwMajorVersion dwMinorVersion Other
/// Windows 10 10.0* 10 0 OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION
/// Windows Server 2016 10.0* 10 0 OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION
/// Windows 8.1 6.3* 6 3 OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION
/// Windows Server 2012 R2 6.3* 6 3 OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION
/// Windows 8 6.2 6 2 OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION
/// Windows Server 2012 6.2 6 2 OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION
/// Windows 7 6.1 6 1 OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION
/// Windows Server 2008 R2 6.1 6 1 OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION
/// Windows Server 2008 6.0 6 0 OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION
/// Windows Vista 6.0 6 0 OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION
/// Windows Server 2003 R2 5.2 5 2 GetSystemMetrics(SM_SERVERR2) != 0
/// Windows Server 2003 5.2 5 2 GetSystemMetrics(SM_SERVERR2) == 0
/// Windows XP 5.1 5 1 Not applicable
/// Windows 2000 5.0 5 0 Not applicable
/// </remarks>
[StructLayout(LayoutKind.Sequential)]
internal struct OuVersionInfoEXA
{
private readonly uint OsVersionInfoSize;
internal readonly uint MajorVersion;
internal readonly uint MinorVersion;
private readonly uint BuildNumber;
private readonly uint PlatformId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
private readonly string CSDVersion;
internal readonly ushort wServicePackMajor;
internal readonly ushort wServicePackMinor;
internal readonly ushort wSuiteMask;
internal readonly char wProductType;
private readonly char wReserved;
}
/// <summary>
/// https://learn.microsoft.com/en-us/windows/win32/api/minidumpapiset/ns-minidumpapiset-minidump_system_info
/// </summary>
private const byte VER_NT_WORKSTATION = 1;
internal static string GetOsVersionInfoToOsName(this in OuVersionInfoEXA info)
{
switch (info.MajorVersion)
{
case 10:
if (info.wProductType == VER_NT_WORKSTATION)
return "Windows 10";
else
return "Windows Server 2016";
case 6:
switch (info.MinorVersion)
{
case 3:
if (info.wProductType == VER_NT_WORKSTATION)
return "Windows 8.1";
else
return "Windows Server 2012 R2";
case 2:
if (info.wProductType == VER_NT_WORKSTATION)
return "Windows 8";
else
return "Windows Server 2012";
case 1:
if (info.wProductType == VER_NT_WORKSTATION)
return "Windows 7";
else
return "Windows Server 2008 R2";
case 0:
return "Windows Server 2008";
default:
return $"Unknown: {info.MajorVersion}:{info.MinorVersion}";
}
case 5:
switch (info.MinorVersion)
{
case 2:
if (GetSystemMetrics(SM_SERVERR2) != 0)
return "Windows Server 2003 R2";
else
return "Windows Server 2003";
case 1:
return "Windows XP";
case 0:
return "Windows 2000";
default:
return $"Unknown: {info.MajorVersion}:{info.MinorVersion}";
}
default:
return $"Unknown: {info.MajorVersion}:{info.MinorVersion}";
}
}
/// <summary>
/// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemmetrics
/// </summary>
[DllImport("user32.dll")]
static extern int GetSystemMetrics(uint smIndex);
internal const int SM_SERVERR2 = 89;
}
I have a class for this about it.
I wrote this class based on an article on Wikipedia.
You can use this class in your project:
class Windows
{
public class Info
{
public string Name = "";
public string fullName = "";
public string UserAgent = "";
public string Type = "";
public string codeName = "";
public string Version = "";
public string buildNumber = "";
}
public static Info GetInfo()
{
string HKLMWinNTCurrent = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion";
string osBuild = Registry.GetValue(HKLMWinNTCurrent, "CurrentBuildNumber", "").ToString();
string fullName = Registry.GetValue(HKLMWinNTCurrent, "productName", "").ToString();
string Type = Environment.Is64BitOperatingSystem ? "x64" : "x84";
string win11 = "Windows 11 version 21H2";
string win10 = "Windows 10 version ";
string win81 = "Windows 8.1";
string win8 = "Windows 8";
string win7 = "Windows 7";
string winVista = "Windows Vista";
string winXP = "Windows XP";
string winMe = "Windows Me";
string win98 = "Windows 98";
string win98_2 = "Windows 98 Second Edition";
string win2000 = "Windows 2000";
string v11 = "Windows NT 11";
string v10 = "Windows NT 10";
string v81 = "Windows NT 6.3";
string v8 = "Windows NT 6.2";
string v7 = "Windows NT 6.1";
string vVista = "Windows NT 6.0";
string vXP1 = "Windows NT 5.2";
string vXP = "Windows NT 5.1";
string vMe = "Windows NT 4.9";
string v98 = "Windows NT 4.1";
string v2000 = "Windows NT 5.0";
switch (osBuild)
{
case "22000":
return new Info()
{
Name = win11,
Version = "21H2",
UserAgent = v11,
buildNumber = "22000",
codeName = "Sun Valley",
fullName = fullName,
Type = Type
};
case "19044":
return new Info()
{
Name = win10 + "21H2",
Version = "21H2",
UserAgent = v10,
buildNumber = "19044",
codeName = "Vibranium",
fullName = fullName,
Type = Type
};
case "19043":
return new Info()
{
Name = win10 + "21H1",
Version = "21H1",
UserAgent = v10,
buildNumber = "19043",
codeName = "Vibranium",
fullName = fullName,
Type = Type
};
case "19042":
return new Info()
{
Name = win10 + "20H2",
Version = "20H2",
UserAgent = v10,
buildNumber = "19042",
codeName = "Vibranium",
fullName = fullName,
Type = Type
};
case "19041":
return new Info()
{
Name = win10 + "2004",
Version = "2004",
UserAgent = v10,
buildNumber = "19041",
codeName = "Vibranium",
fullName = fullName,
Type = Type
};
case "18363":
return new Info()
{
Name = win10 + "1909",
Version = "1909",
UserAgent = v10,
buildNumber = "18363",
codeName = "Vibranium",
fullName = fullName,
Type = Type
};
case "18362":
return new Info()
{
Name = win10 + "1903",
Version = "1903",
UserAgent = v10,
buildNumber = "18362",
codeName = "19H1",
fullName = fullName,
Type = Type
};
case "17763":
return new Info()
{
Name = win10 + "1809",
Version = "1809",
UserAgent = v10,
buildNumber = "17763",
codeName = "Redstone 5",
fullName = fullName,
Type = Type
};
case "17134":
return new Info()
{
Name = win10 + "1803",
Version = "1803",
UserAgent = v10,
buildNumber = "17134",
codeName = "Redstone 4",
fullName = fullName,
Type = Type
};
case "16299":
return new Info()
{
Name = win10 + "1709",
Version = "1709",
UserAgent = v10,
buildNumber = "16299",
codeName = "Redstone 3",
fullName = fullName,
Type = Type
};
case "15063":
return new Info()
{
Name = win10 + "1703",
Version = "1703",
UserAgent = v10,
buildNumber = "15063",
codeName = "Redstone 2",
fullName = fullName,
Type = Type
};
case "14393":
return new Info()
{
Name = win10 + "1607",
Version = "1607",
UserAgent = v10,
buildNumber = "14393",
codeName = "Redstone 1",
fullName = fullName,
Type = Type
};
case "10586":
return new Info()
{
Name = win10 + "1511",
Version = "1511",
UserAgent = v10,
buildNumber = "10586",
codeName = "Threshold 2",
fullName = fullName,
Type = Type
};
case "10240":
return new Info()
{
Name = win10 + "1507",
Version = "NT 10.0",
UserAgent = v10,
buildNumber = "10240",
codeName = "Threshold 1",
fullName = fullName,
Type = Type
};
case "9600":
return new Info()
{
Name = win81,
Version = "NT 6.3",
UserAgent = v81,
buildNumber = "9600",
codeName = "Blue",
fullName = fullName,
Type = Type
};
case "9200":
return new Info()
{
Name = win8,
Version = "NT 6.2",
UserAgent = v8,
buildNumber = "9200",
codeName = win8,
fullName = fullName,
Type = Type
};
case "7601":
return new Info()
{
Name = win7,
Version = "NT 6.1",
UserAgent = v7,
buildNumber = "7601",
codeName = win7,
fullName = fullName,
Type = Type
};
case "6002":
return new Info()
{
Name = winVista,
Version = "NT 6.0",
UserAgent = vVista,
buildNumber = "6002",
codeName = "Longhorn",
fullName = fullName,
Type = Type
};
case "2715":
return new Info()
{
Name = winXP,
Version = "NT 5.2",
UserAgent = vXP1,
buildNumber = "2715",
codeName = "Emerald",
fullName = fullName,
Type = Type
};
case "3790":
return new Info()
{
Name = winXP,
Version = "NT 5.2",
UserAgent = vXP1,
buildNumber = "3790",
codeName = "Anvil",
fullName = fullName,
Type = Type
};
case "2600":
return new Info()
{
Name = winXP,
Version = "NT 5.1",
UserAgent = vXP,
buildNumber = "2600",
codeName = "Symphony, Harmony, Freestyle, Whistler",
fullName = fullName,
Type = Type
};
case "3000":
return new Info()
{
Name = winMe,
Version = "4.9",
UserAgent = vMe,
buildNumber = "3000",
codeName = "Millennium",
fullName = fullName,
Type = Type
};
case "1998":
return new Info()
{
Name = win98,
Version = "4.10",
UserAgent = v98,
buildNumber = "1998",
codeName = "Memphis",
fullName = fullName,
Type = Type
};
case "2222":
return new Info()
{
Name = win98_2,
Version = "4.10",
UserAgent = v98,
buildNumber = "2222",
codeName = "Unknow",
fullName = fullName,
Type = Type
};
case "2195":
return new Info()
{
Name = win2000,
Version = "NT 5.0",
UserAgent = v2000,
buildNumber = "2195",
codeName = "Windows NT 5.0",
fullName = fullName,
Type = Type
};
default:
return new Info()
{
Name = "Unknow",
Version = "Unknow",
UserAgent = "Unknow",
buildNumber = "Unknow",
codeName = "Unknow"
};
}
}
}
and about use this,
var info = Windows.GetInfo();
Console.WriteLine($"Name: {info.Name}");
Console.WriteLine($"fullName: {info.fullName}");
Console.WriteLine($"UserAgent: {info.UserAgent}");
Console.WriteLine($"Type: {info.Type}");
Console.WriteLine($"codeName: {info.codeName}");
Console.WriteLine($"Version: {info.Version}");
Console.WriteLine($"buildNumber: {info.buildNumber}");
Result:
Name: Windows 10 version 21H2
fullName: Windows 10 Enterprise LTSC 2021
UserAgent: Windows NT 10
Type: x64
codeName: Vibranium
Version: 21H2
buildNumber: 19044
Don't over complicate the problem.
string osVer = System.Environment.OSVersion.Version.ToString();
if (osVer.StartsWith("5")) // windows 2000, xp win2k3
{
MessageBox.Show("xp!");
}
else // windows vista and windows 7 start with 6 in the version #
{
MessageBox.Show("Win7!");
}
精彩评论