如何检查应用是否运行在Windows Server 2012及以上系统?
判断应用是否运行在Windows Server 2012及以上版本
嘿,这个需求我熟!你已经能判断系统是不是Windows Server了,接下来只需要结合版本校验,就能轻松实现“是否是2012及以上版本”的判断。我给你两种靠谱的实现方案,你可以根据自己的场景选择:
方案一:结合GetVersionEx(需兼容性清单)
这个方案基于你现有的代码,先判断是否为Server系统,再获取系统NT版本号(Windows Server 2012对应NT 6.2,2012 R2是6.3,2016及以后是10.0),判断是否大于等于6.2即可。
完整代码如下:
using System; using System.Runtime.InteropServices; class OS { public static bool IsWindowsServer() { return IsOS(OS_ANYSERVER); } public static bool IsWindowsServer2012OrNewer() { // 第一步:先确认是Server系统 if (!IsWindowsServer()) return false; // 获取系统版本信息 var versionInfo = new OSVERSIONINFOEX(); versionInfo.dwOSVersionInfoSize = Marshal.SizeOf(versionInfo); if (!GetVersionEx(ref versionInfo)) return false; // Windows Server 2012对应的NT版本是6.2,判断版本是否达标 if (versionInfo.dwMajorVersion > 6) return true; return versionInfo.dwMajorVersion == 6 && versionInfo.dwMinorVersion >= 2; } const int OS_ANYSERVER = 29; [DllImport("shlwapi.dll", SetLastError = true, EntryPoint = "#437")] private static extern bool IsOS(int os); [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 ushort wServicePackMajor; public ushort wServicePackMinor; public ushort wSuiteMask; public byte wProductType; public byte wReserved; } [DllImport("kernel32.dll", SetLastError = true)] private static extern bool GetVersionEx(ref OSVERSIONINFOEX osVersionInfo); static void Main(string[] args) { Console.WriteLine($"是否为Windows Server系统:{IsWindowsServer()}"); Console.WriteLine($"是否为Windows Server 2012及以上:{IsWindowsServer2012OrNewer()}"); } }
注意事项
在Windows 8.1/Server 2012 R2及以后的系统中,GetVersionEx会返回兼容性版本号(6.2),而非真实版本。解决方法是在你的项目中添加应用程序清单文件,并加入兼容性声明:
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <application> <!-- 声明支持的Windows版本 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> <!-- Windows 10/11/Server 2016+ --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> <!-- Windows 8.1/Server 2012 R2 --> <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> <!-- Windows 8/Server 2012 --> </application> </compatibility>
方案二:使用VerifyVersionInfo(无需清单,更可靠)
微软推荐使用VerifyVersionInfo进行版本检查,它不受兼容性清单的影响,能直接获取真实版本信息,是更稳妥的选择。
完整代码如下:
using System; using System.Runtime.InteropServices; class OS { public static bool IsWindowsServer() { return IsOS(OS_ANYSERVER); } public static bool IsWindowsServer2012OrNewer() { // 第一步:确认是Server系统 if (!IsWindowsServer()) return false; var versionInfo = new OSVERSIONINFOEX(); versionInfo.dwOSVersionInfoSize = Marshal.SizeOf(versionInfo); // 设置要检查的最低版本:NT 6.2(对应Server 2012) versionInfo.dwMajorVersion = 6; versionInfo.dwMinorVersion = 2; versionInfo.wProductType = VER_NT_SERVER; // 限定检查Server系统 // 构建检查条件:主版本>=6,副版本>=2,产品类型是Server ulong conditionMask = 0; conditionMask = VerSetConditionMask(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL); conditionMask = VerSetConditionMask(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL); conditionMask = VerSetConditionMask(conditionMask, VER_PRODUCT_TYPE, VER_EQUAL); // 执行版本校验 return VerifyVersionInfo(ref versionInfo, VER_MAJORVERSION | VER_MINORVERSION | VER_PRODUCT_TYPE, conditionMask); } const int OS_ANYSERVER = 29; private const byte VER_NT_SERVER = 0x00000003; private const uint VER_MAJORVERSION = 0x00000002; private const uint VER_MINORVERSION = 0x00000004; private const uint VER_PRODUCT_TYPE = 0x00000080; private const byte VER_GREATER_EQUAL = 3; private const byte VER_EQUAL = 1; [DllImport("shlwapi.dll", SetLastError = true, EntryPoint = "#437")] private static extern bool IsOS(int os); [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 ushort wServicePackMajor; public ushort wServicePackMinor; public ushort wSuiteMask; public byte wProductType; public byte wReserved; } [DllImport("kernel32.dll", SetLastError = true)] private static extern bool VerifyVersionInfo(ref OSVERSIONINFOEX osVersionInfo, uint dwTypeMask, ulong dwlConditionMask); [DllImport("kernel32.dll")] private static extern ulong VerSetConditionMask(ulong dwlConditionMask, uint dwTypeBitMask, byte dwConditionMask); static void Main(string[] args) { Console.WriteLine($"是否为Windows Server系统:{IsWindowsServer()}"); Console.WriteLine($"是否为Windows Server 2012及以上:{IsWindowsServer2012OrNewer()}"); } }
这个方案不需要额外添加清单文件,直接就能准确判断版本,推荐优先使用。
内容的提问来源于stack exchange,提问作者user9250176




