OdysseusYuan/LKY_OfficeTools · error · Exception

无法获取 PerpetualVL2021 对应的版本号!

Error message

无法获取 PerpetualVL2021 对应的版本号!

What it means

Thrown when the PerpetualVL2021 (Office 2021 LTSC) channel block's version cannot be parsed from OfficeChannelInfo. The code uses Com_TextOS.GetCenterText with string markers ("PerpetualVL2021", ... name) to extract the block, then reads latestUpdateVersion. This fires when the PerpetualVL2021 block is absent from Microsoft's channel data (channel renamed/removed) or when the version field marker is not found within it. It is fragile string-scraping of Microsoft's channel XML/JSON rather than structured parsing.

Source

Thrown at LKY_OfficeTools/Lib/Lib_OfficeInfo.cs:136

                        {
                            return null;
                        }

                        new Log("\n------> 正在解析 最新可用 Office 版本 ...", ConsoleColor.DarkCyan);

                        //获取版本信息
                        string latest_info = Com_TextOS.GetCenterText(OfficeChannelInfo, "\"PerpetualVL2021\",", "name");                     //获取 2021 LTSC
                        if (!string.IsNullOrEmpty(latest_info))
                        {
                            //获取版本号
                            var ver = new Version(Com_TextOS.GetCenterText(latest_info, "latestUpdateVersion\":\"", "\""));      //官方Json取值,格式和自己的不一样,千万注意

                            new Log($"     √ 已获得 Office 最新版本为:v{ver}", ConsoleColor.DarkGreen);

                            return _office_latest_version = ver;
                        }

                        throw new Exception("无法获取 PerpetualVL2021 对应的版本号!");
                    }
                    catch (Exception Ex)
                    {
                        new Log("     × 无法获取 最新可用 Office 版本,请稍后重试!", ConsoleColor.DarkRed);
                        new Log(Ex.ToString());
                        return null;
                    }
                }
            }

            private static string _office_url_root;
            internal static string OfficeUrlRoot
            {
                get
                {
                    try
                    {
                        //非空返回

View on GitHub (pinned to 6f9a1bd471)

Solutions

  1. Dump the raw OfficeChannelInfo content to inspect whether a "PerpetualVL2021" block still exists.
  2. If the block was renamed, update the left marker in GetCenterText to the new channel identifier.
  3. If latestUpdateVersion was renamed, update the inner marker string to match Microsoft's current field name.
  4. Replace string-marker scraping with a real JSON parser (e.g. System.Text.Json / Newtonsoft) to survive field reordering.
  5. Add a unit test against a saved sample of the channel JSON so format drift is caught early.

Example fix

// before
string latest_info = Com_TextOS.GetCenterText(OfficeChannelInfo, "\"PerpetualVL2021\",", "name");
if (!string.IsNullOrEmpty(latest_info))
{
    var ver = new Version(Com_TextOS.GetCenterText(latest_info, "latestUpdateVersion\":\"", "\""));
    return _office_latest_version = ver;
}
throw new Exception("无法获取 PerpetualVL2021 对应的版本号!");

// after — structured parsing with a clear missing-channel error
var json = JObject.Parse(OfficeChannelInfo);
var channel = json["PerpetualVL2021"];
if (channel == null)
    throw new Exception("PerpetualVL2021 频道不存在,可能已被微软重命名或移除。");
var ver = new Version(channel["latestUpdateVersion"].ToString());
return _office_latest_version = ver;
Defensive patterns

Strategy: fallback

Validate before calling

// Sanity-check the channel block presence before parsing the version.
string latest_info = Com_TextOS.GetCenterText(OfficeChannelInfo, "\"PerpetualVL2021\",", "name");
if (string.IsNullOrEmpty(latest_info))
{
    new Log("OfficeChannelInfo 中未找到 PerpetualVL2021 频道块,微软可能已更改频道结构。", ConsoleColor.DarkRed);
    return;
}

Type guard

// Narrow a parsed version string before constructing Version (which throws on malformed input).
bool TryParseOfficeVersion(string raw, out Version ver)
{
    ver = null;
    if (string.IsNullOrWhiteSpace(raw)) return false;
    return Version.TryParse(raw.Trim('"', ' '), out ver);
}

Prevention

When it happens

Trigger: (a) Microsoft's channel data no longer contains a "PerpetualVL2021" channel block (renamed or deprecated); (b) the block exists but the latestUpdateVersion field marker is absent or reformatted; (c) the extracted version string is malformed so new Version() throws (that case is caught by the outer handler and returns null, but indicates the same root cause).

Common situations: Microsoft restructured or renamed the Office 2021 LTSC channel; the channel JSON field ordering/format changed; only Microsoft 365 channels are published and PerpetualVL2021 was dropped; Microsoft changed escaping in the JSON so the raw-quote markers no longer match.

Related errors


AI-assisted analysis of OdysseusYuan/LKY_OfficeTools@6f9a1bd471 (2026-08-13). Data as JSON: /api/errors/a2b380b9b78c7b18. Report an issue: GitHub.