C++版clover支持安装net3.5,仅限于本地,因为下载站不会放那么大的包
大石头 authored at 2025-07-07 20:34:42
4.59 KiB
LuckyClover
using System;
using System.Collections.Generic;

namespace LuckyClover;

/// <summary>.NET 运行时版本策略。核心运行时只保留 LTS(net6/net8/net10)与最新 STS(net11),且始终安装最新补丁版本。</summary>
/// <remarks>修改版本号时,必须同步修改 Clover(C++)中的同名常量,保证 C# 与 C++ 安装器一致。</remarks>
public static class NetVersions
{
    #region 静态定义
    /// <summary>.NET6 LTS 最新补丁版本</summary>
    public const String Version6 = "6.0.36";

    /// <summary>.NET8 LTS 最新补丁版本</summary>
    public const String Version8 = "8.0.33";

    /// <summary>.NET10 LTS 最新补丁版本</summary>
    public const String Version10 = "10.0.14";

    /// <summary>.NET11 STS 最新版本</summary>
    public const String Version11 = "11.0.0";
    #endregion

    #region 方法
    /// <summary>获取受支持的核心运行时版本</summary>
    /// <returns>按版本从低到高排列的版本号数组</returns>
    public static String[] GetSupportedVersions() => new[] { Version6, Version8, Version10, Version11 };

    /// <summary>按操作系统获取自动安装的目标运行时</summary>
    /// <param name="osVer">操作系统版本</param>
    /// <param name="isServer">是否服务器版操作系统</param>
    /// <returns>运行时简称数组,如 net48、net10</returns>
    public static String[] GetAutoTargets(Version osVer, Boolean isServer = false)
    {
        if (osVer == null) return new String[0];

        // Windows 2000/XP/2003 只支持 .NET Framework 2.0/4.0
        if (osVer.Major <= 5) return new[] { "net20", "net40" };

        // Vista/Server 2008,4.5.2 是最后支持的版本
        if (osVer.Major == 6 && osVer.Minor == 0) return new[] { "net45" };

        // Win7/Server 2008 R2,只有 SP1 才支持 .NET Core
        if (osVer.Major == 6 && osVer.Minor == 1)
        {
            if (osVer.Build >= 7601) return new[] { "net48", "net6" };
            return new[] { "net48" };
        }

        // Win8/8.1/Server 2012/2012 R2
        if (osVer.Major == 6)
        {
            // Win8(6.2)客户端不受 .NET Core 支持,Server 2012 受支持
            if (osVer.Minor >= 3 || isServer) return new[] { "net48", "net6" };
            return new[] { "net48" };
        }

        // Win10 1607+/Win11/Server 2016+
        if (osVer.Major >= 10 && osVer.Build >= 14393) return new[] { "net48", "net10" };

        return new[] { "net48" };
    }

    /// <summary>获取 dotnet 共享运行时目录</summary>
    /// <returns>可能的 shared 目录列表</returns>
    public static String[] GetDotnetSharedDirs()
    {
        var list = new List<String>();

        // 32位进程在64位系统中会被重定向到 Program Files (x86),三个目录都要检查
        var pf = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
        if (!String.IsNullOrEmpty(pf)) list.Add(pf + "\\dotnet\\shared");

        var pf64 = Environment.GetEnvironmentVariable("ProgramW6432");
        if (!String.IsNullOrEmpty(pf64)) list.Add(pf64 + "\\dotnet\\shared");

        var pf86 = Environment.GetEnvironmentVariable("ProgramFiles(x86)");
        if (!String.IsNullOrEmpty(pf86)) list.Add(pf86 + "\\dotnet\\shared");

        list.Add("/usr/share/dotnet/shared");
        list.Add("/usr/lib/dotnet/shared");

        return list.ToArray();
    }

    /// <summary>判断核心运行时是否支持当前操作系统</summary>
    /// <param name="target">目标版本,如 6.0.36</param>
    /// <param name="osVer">操作系统版本</param>
    /// <param name="isServer">是否服务器版操作系统</param>
    /// <returns>是否支持</returns>
    public static Boolean IsSupported(String target, Version osVer, Boolean isServer = false)
    {
        if (String.IsNullOrEmpty(target) || osVer == null) return false;

        var major = 0;
        var ss = target.Split('.');
        if (ss.Length > 0) Int32.TryParse(ss[0], out major);
        if (major == 0) return false;

        // Win10 1607 起支持所有核心运行时
        if (osVer.Major >= 10) return osVer.Build >= 14393;

        if (major == 6)
        {
            if (osVer.Major != 6) return false;

            // .NET6 支持 Win7 SP1、Win8.1 与 Server 2012+,Win8 客户端不支持
            if (osVer.Minor == 1) return osVer.Build >= 7601;
            if (osVer.Minor == 2) return isServer;

            return true;
        }

        // .NET8/10/11 仅支持 Server 2012/2012 R2 及以上
        if (major is 8 or 10 or 11) return isServer && osVer.Major == 6 && osVer.Minor >= 2;

        return false;
    }
    #endregion
}