{"record":{"id":"99be0585831592ab","repo":"babalae/better-genshin-impact","slug":"error-99be05","errorCode":null,"errorMessage":"要启动的程序不存在。","messagePattern":"要启动的程序不存在。","errorType":"exception","errorClass":"FileNotFoundException","httpStatus":null,"severity":"error","filePath":"BetterGenshinImpact/Service/ChildSession/ChildSessionProcessLauncher.cs","lineNumber":203,"sourceCode":"                    // 临时任务启动成功后，清理失败不应中断已经启动的目标程序。\n                }\n            }\n\n            ReleaseComObject(runningTaskObject);\n            ReleaseComObject(registeredTaskObject);\n            ReleaseComObject(actionObject);\n            ReleaseComObject(taskDefinitionObject);\n            ReleaseComObject(rootFolderObject);\n            ReleaseComObject(schedulerObject);\n        }\n    }\n\n    private static string ValidateExecutablePath(string executablePath)\n    {\n        var fullPath = Path.GetFullPath(executablePath);\n        if (!File.Exists(fullPath))\n        {\n            throw new FileNotFoundException(\"要启动的程序不存在。\", fullPath);\n        }\n\n        if (!string.Equals(Path.GetExtension(fullPath), \".exe\", StringComparison.OrdinalIgnoreCase))\n        {\n            throw new ArgumentException(\"当前只允许选择 .exe 程序。\", nameof(executablePath));\n        }\n\n        return fullPath;\n    }\n\n    private static string QuoteArgument(string argument)\n    {\n        return $\"\\\"{argument.Replace(\"\\\"\", \"\\\\\\\"\", StringComparison.Ordinal)}\\\"\";\n    }\n\n    private static void ReleaseComObject(object? value)\n    {\n        if (value is not null && Marshal.IsComObject(value))","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/Service/ChildSession/ChildSessionProcessLauncher.cs#L185-L221","documentation":"Thrown by ValidateExecutablePath when File.Exists returns false for the resolved full path. The FileNotFoundException carries the path as fileName so the caller can see which file was missing.","triggerScenarios":"LaunchElevatedAsync(childSessionId, executablePath) is called with a path whose target was deleted, moved, or never existed; the path is on a network share that is currently disconnected; the path contains an unexpanded variable or relative segment that resolves to a non-existent location.","commonSituations":"User selected an executable earlier, then moved/deleted it; executable lives on a removable drive that was ejected; path was typed manually with a typo; UNC path to an offline share.","solutions":["Verify the executable exists at the given absolute path before invoking launch.","Re-select the executable file in the UI to capture a fresh path.","Use a local absolute path rather than a network/removable location."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"var fullPath = Path.GetFullPath(executablePath);\nif (!File.Exists(fullPath))\n{\n    throw new FileNotFoundException(\"要启动的程序不存在。\", fullPath);\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    await ChildSessionProcessLauncher.LaunchElevatedAsync(childSessionId, exePath);\n}\ncatch (FileNotFoundException ex)\n{\n    logger.LogError(ex, \"Executable not found: {FileName}\", ex.FileName);\n}","preventionTips":["Capture the executable path at launch time rather than caching a stale selection.","Prefer local absolute paths over network/removable locations.","Validate File.Exists in the UI before enabling the launch button."],"tags":["filesystem","validation","path","child-session"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}