在 .NET 中检测 Windows 版本
Posted
技术标签:
【中文标题】在 .NET 中检测 Windows 版本【英文标题】:Detect Windows version in .NET 【发布时间】:2011-02-18 16:21:11 【问题描述】:如何在 .NET 中检测 Windows 操作系统版本?
我可以使用什么代码?
【问题讨论】:
【参考方案1】:System.Environment.OSVersion
包含区分大多数 Windows 操作系统主要版本(但不是全部)所需的信息。它由映射到以下 Windows 版本的三个组件组成:
+------------------------------------------------------------------------------+
| | 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 |
+------------------------------------------------------------------------------+
有关可让您更全面地了解当前执行环境正在其中运行的确切 Windows 版本的库,请查看this library。
重要提示:如果您的可执行程序集清单未明确声明您的 exe 程序集与 Windows 8.1 和 Windows 10.0 兼容,System.Environment.OSVersion
将返回 Windows 8 版本,即 6.2,而不是6.3 和 10.0!来源:here。
更新:在 .NET 5.0 及更高版本中,System.Environment.OSVersion
始终返回实际的操作系统版本。如需更多信息,请参阅Environment.OSVersion returns the correct operating system version。
【讨论】:
此表至少部分不正确,这使得答案(最初是关于 Win7)不正确。人们在没有检查它是否真的有效的情况下投票。 Win7 在我的机器上没有 2 的未成年人。我在 Win7 SP1 上,我的版本信息显示“Microsoft Windows NT 6.1.7601 Service Pack 1”。查看 Environment.OSVersion 给出 Build=7601, Major=6, MajorRevision=1, Minor=1, MinorRevision=0, Revision=65536。 我同意其他人的观点。这实际上并没有回答这个问题。 Gabe 的回答是:***.com/questions/2819934/detect-windows-7-in-net/… @Andrew 他和我对 Windows 7 有相同的答案,只是他实际上并没有解决 Windows 2008 使用这些特定属性看起来相同 好,现在您应该使用 Windows 8 和最新的 Windows Server (2012) 更新表格 :) 更多信息在这里解释为什么这个解决方案可能不适用于 Windows 8 以上的版本:msdn.microsoft.com/en-us/library/windows/desktop/…【参考方案2】:当我必须确定各种 Microsoft 操作系统版本时,我使用了它:
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;
来源:here
【讨论】:
getOSArchitecture() 方法呢?错误:“名称 'getOSArchitecture' 在当前上下文中不存在。” @LonnieBest - 那是一种判断是x64还是x86的方法……我没用,注释掉就好了。vs.Minor != 0
不一定是XP
或7
。它可能是任何具有相同次要版本的服务器版本。请参阅此处msdn.microsoft.com/en-us/library/windows/desktop/…
我这里有 Windows 10,它返回为 Windows 8。
@MatheusMiranda - 请参阅已接受答案末尾的 重要说明:“重要说明:如果您的可执行程序集清单未明确声明您的 exe 程序集是与 Windows 8.1 和 Windows 10.0 兼容,System.Environment.OSVersion 将返回 Windows 8.0 版本?!是 6.2,而不是 6.3 和 10.0!!"【参考方案3】:
我使用命名空间System.Management
的ManagementObjectSearcher
例子:
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);
不要忘记添加对Assembly
System.Management.dll
的引用 并使用:using System.Management;
结果:
Documentation
【讨论】:
完美,这应该标记为答案,其他解决方案不一致。+1【参考方案4】:这是一个比较老的问题,但我最近不得不解决这个问题,但没有看到我的解决方案发布在任何地方。
最简单(在我看来也是最简单的方法)是对 RtlGetVersion 使用 pinvoke 调用
[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;
此结构中的主要和次要版本号对应于已接受答案表中的值。
这将返回正确的 Windows 版本号,这与 kernel32 中已弃用的 GetVersion 和 GetVersionEx 函数不同
【讨论】:
国际海事组织,这是最好的答案。使用 .Net 的 Environment.OSVersion 需要操作清单才能正常工作,而使用 WMI 需要引入额外的依赖项。简单、直接、不复杂。 或者更好的是使用 RtlGetNtVersionNumbers()... 并且不需要任何结构。 如果用户启用了当前应用程序的兼容模式,这是否也会返回正确的版本? 我们如何使用这种机制获得ServicePackMajor
、ServicePackMinor
和操作系统版本?
@RBT 抱歉这么晚的答案,这个函数也接受OSVERSIONINFOEXW structure(其中包含你需要的字段),这也是这个答案中存在错误的地方 - OsVersionInfoSize
必须在调用之前设置,这样RtlGetVersionInfo
就能够区分这两种结构类型。【参考方案5】:
你可以使用这个辅助类;
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
示例代码在这里:
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 );
我是在这个地址找到的:http://www.csharp411.com/wp-content/uploads/2009/01/OSInfo.cs
【讨论】:
是的,此代码对于主要版本 6 不完整。它需要打开次要版本以及现有的产品类型开关。 (6.0 和 6.1 的含义因产品类型而异。) 你是从这里拿的吗:csharp411.com/wp-content/uploads/2009/01/OSInfo.cs?请给予信用.. 请注意,版本版本列表已过时。更新后的列表可以从msdn.microsoft.com/en-us/library/windows/desktop/… 的表中得到【参考方案6】:就像 R. Bemrose 建议的那样,如果您正在使用 Windows 7 特定功能,您应该查看Windows® API Code Pack for Microsoft® .NET Framework。
它包含一个CoreHelpers
类,可让您确定当前使用的操作系统(仅限 XP 及更高版本,现在是 .NET 的要求)
它还提供了多种辅助方法。例如,假设您要使用 Windows 7 的跳转列表,有一个类 TaskbarManager
提供了一个名为 IsPlatformSupported
的属性,如果您使用的是 Windows 7 及更高版本,它将返回 true。
【讨论】:
【参考方案7】:通过Environment.OSVersion
“获取一个包含当前平台标识符和版本号的 System.OperatingSystem 对象。”
【讨论】:
【参考方案8】:对于一个非常简单的函数,这些似乎都是非常复杂的答案:
public bool IsWindows7
get
return (Environment.OSVersion.Version.Major == 6 &
Environment.OSVersion.Version.Minor == 1);
【讨论】:
注意:对于 Windows Server 2008 R2,这也将返回 True 警告:这种方法是not recommended by Microsoft。【参考方案9】:-
添加对
Microsoft.VisualBasic
的引用。
包含命名空间using Microsoft.VisualBasic.Devices
;
使用new ComputerInfo().OSFullName
返回值为“Microsoft Windows 10 Enterprise”
【讨论】:
【参考方案10】:检测操作系统版本:
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();
【讨论】:
【参考方案11】:一种方式:
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";
然后简单地在函数周围包裹一个选择案例。
【讨论】:
与原帖无关,但如果主版本是 5,那么您有三个可能的 Windows 版本:5.0 = Windows 2000、5.1 = 32 位 Windows XP、5.2 = Windows Server 2003 或64 位 Windows XP【参考方案12】:以上答案将在 Windows 10 上给我Major
版本6
。
我发现无需添加额外的 VB 库即可工作的解决方案如下:
var versionString = (string)Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows NT\\CurrentVersion")?.GetValue("productName");
我不认为这是获取版本的最佳方式,但好处是 oneliner 没有额外的库,在我的情况下检查它是否包含 "10"
就足够了。
【讨论】:
【参考方案13】:第一个解决方案
为确保您使用Environment.OSVersion
获得正确的版本,您应该使用Visual Studio 添加app.manifest
并取消注释supportedOS
标记:
<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>
然后在你的代码中你可以像这样使用Environment.OSVersion
:
var version = System.Environment.OSVersion;
Console.WriteLine(version);
示例
例如,在我的机器 (Windows 10.0 Build 18362.476
) 中,结果会是这样,这是不正确:
Microsoft Windows NT 6.2.9200.0
通过添加app.manifest
并取消注释这些标签我会得到正确的版本号:
Microsoft Windows NT 10.0.18362.0
替代解决方案
如果您不喜欢将 app.manifest
添加到您的项目中,您可以使用自 .NET Framework 4.7.1 和 .NET Core 1.0 起提供的 OSDescription
。
string description = RuntimeInformation.OSDescription;
注意:不要忘记在文件顶部添加以下 using 语句。
using System.Runtime.InteropServices;
您可以阅读更多关于它和支持的平台here。
【讨论】:
【参考方案14】:这个问题可以追溯到 Windows XP 时代,多年来,问题和答案都经过编辑。
以下代码使用 .NET Framework 工作,应检测所有 Windows 10 版本。
基于这个问答——(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();
我在电脑上测试了一下,结果如下。
有关 Windows 10 版本列表,请参阅此 Wikipedia 文章
https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions
【讨论】:
这是一个完整的证明答案,在所有情况下都提供准确的信息。唯一的问题是您的应用程序可能需要管理员权限才能访问注册表。那里有一些更有用的键,即 InstallationType(客户端/服务器)、CurrentMajorVersionNumber、CurrentMinorVersionNumber、EditionID(企业版、专业版、家庭版等),任何人都可以使用。【参考方案15】:如何使用注册表来获取名称。
“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion”自 Windows XP 以来的值为 ProductName。
[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;
如果您使用的是 .NET Framework 4.0 或更高版本。您可以删除 Is64BitOperatingSystem() 方法并使用Environment.Is64BitOperatingSystem。
【讨论】:
【参考方案16】:阅读 WinAPI 文档后,我生成了一个静态类,该类应正确返回操作系统版本的名称。我从 WinAPI 中添加了一些 cmets 和文档链接。
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://docs.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://docs.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://docs.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://docs.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;
【讨论】:
【参考方案17】:不要使问题过于复杂。
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!");
【讨论】:
呃,如果它以 5 开头,我有三分之一的机会猜到操作系统? -1 因为您将版本转换为字符串并将其与数字字符串进行比较,而您本来可以只比较版本的Major
部分。加上它报告“Win7!”在 Windows NT/Me/98/95 操作系统上。它也不能很好地应对未来版本的操作系统
教科书示例如何不解决此类问题。以上是关于在 .NET 中检测 Windows 版本的主要内容,如果未能解决你的问题,请参考以下文章