{"record":{"id":"ce89657b241f756d","repo":"ZyperWave/ZyperWinOptimize","slug":"optimize-ce8965","errorCode":null,"errorMessage":"配置文件未加载","messagePattern":"配置文件未加载","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"ZyperWin++/ZyperWin++/Optimize.cs","lineNumber":3066,"sourceCode":"\r\n                // 设置分类节点的选中状态\r\n                if (allChecked && category.Sub.Count > 0)\r\n                    category.Checked = true;\r\n                else if (anyChecked)\r\n                    category.Checked = true; // 或者保持 indeterminate 状态\r\n                else\r\n                    category.Checked = false;\r\n            }\r\n        }\r\n\r\n        // 优化或还原完成后刷新状态\r\n        private async Task PerformOptimizationWithProgress(bool isRestore)\r\n        {\r\n            Console.WriteLine($\"开始执行{(isRestore ? \"还原\" : \"优化\")}操作...\");\r\n\r\n            if (xmlDoc == null)\r\n            {\r\n                throw new Exception(\"配置文件未加载\");\r\n            }\r\n\r\n            // 收集所有选中的项目\r\n            var selectedItems = new List<(string category, string itemTag, bool alreadyOptimized)>();\r\n            foreach (var category in tree1.Items)\r\n            {\r\n                foreach (var item in category.Sub)\r\n                {\r\n                    if (item.Checked && item.Tag != null)\r\n                    {\r\n                        string itemTag = item.Tag.ToString();\r\n                        bool isAlreadyOptimized = optimizationStatus.ContainsKey(itemTag) && optimizationStatus[itemTag];\r\n\r\n                        // 还原操作不管是否优化过都执行\r\n                        // 优化操作跳过已优化的项目\r\n                        if (!isRestore && isAlreadyOptimized)\r\n                        {\r\n                            Console.WriteLine($\"跳过已优化的项目: {itemTag}\");\r","sourceCodeStart":3048,"sourceCodeEnd":3084,"githubUrl":"https://github.com/ZyperWave/ZyperWinOptimize/blob/d20e78bbd906fa179e4cc9f5107b502da5967aa9/ZyperWin++/ZyperWin++/Optimize.cs#L3048-L3084","documentation":"PerformOptimizationWithProgress requires the XML configuration document (xmlDoc) to be loaded before it can map selected tree items to registry/service operations. If xmlDoc is null it throws \"配置文件未加载\". This is an internal state guard: the optimization flow was invoked before initialization finished.","triggerScenarios":"Clicking optimize or restore while the Optimize control is still loading its XML config asynchronously, or after config loading silently failed (Config folder missing/corrupt XML), so xmlDoc was never assigned.","commonSituations":"User clicks apply within seconds of opening the page on slow disk; app deployed without the Config folder; XML config failed to parse during Load (exception swallowed earlier); race between async load and button enable.","solutions":["Ensure the Config folder ships with the app and contains the expected XML file; reload the page to retry loading.","Check earlier logs (Console.WriteLine '开始执行...' appears only after load attempt) for a swallowed XML parse failure.","Disable the optimize/restore buttons until xmlDoc != null; enable them after loading completes.","Await the config-load task before allowing PerformOptimizationWithProgress to run (guard in button handler)."],"exampleFix":"// before (button handler)\nawait PerformOptimizationWithProgress(isRestore);\n// after\nif (xmlDoc == null)\n{\n    MessageBox.Show(\"配置仍在加载或加载失败，请稍候重试。\");\n    return;\n}\nawait PerformOptimizationWithProgress(isRestore);","handlingStrategy":"validation","validationCode":"if (xmlDoc == null)\n{\n    MessageBox.Show(\"配置尚未加载完成，请稍候再试。\");\n    return;\n}\n// or gate the UI:\nbuttonApply.Enabled = xmlDoc != null;","typeGuard":"bool ConfigReady() => xmlDoc != null;","tryCatchPattern":"try { await PerformOptimizationWithProgress(isRestore); }\ncatch (Exception ex) when (ex.Message == \"配置文件未加载\")\n{ MessageBox.Show(\"配置文件未加载，请重新打开本页面或检查 Config 目录。\", \"错误\", MessageBoxButtons.OK, MessageBoxIcon.Error); }","preventionTips":["Load the XML config in the constructor and await it before wiring buttons.","Enable action buttons only after config load succeeds.","Fail loudly (log + UI) if the Config XML fails to parse instead of silently leaving xmlDoc null.","Ship and verify the Config folder at startup."],"tags":["null-reference","async-race","config-not-loaded","windows"],"backgroundTag":"missing-required-config","analyzedSha":"d20e78bbd906fa179e4cc9f5107b502da5967aa9","analyzedAt":"2026-09-13T15:15:37.168Z","contentChangedAt":"2026-09-13T15:15:37.168Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}