You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何检查应用是否运行在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

火山引擎 最新活动