{"record":{"id":"2094be802be1ce17","repo":"babalae/better-genshin-impact","slug":"bvflow","errorCode":null,"errorMessage":"同一个 BvFlow 不能并发执行","messagePattern":"同一个 BvFlow 不能并发执行","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"BetterGenshinImpact/Core/BgiVision/BvFlow.cs","lineNumber":218,"sourceCode":"        return AddWaitStep(ParseTargets(targets, nameof(targets)), BvFlowCondition.AllDisappear,\n            timeout, retryInterval);\n    }\n\n    public BvFlow Wait(int milliseconds)\n    {\n        if (milliseconds < 0)\n        {\n            throw new ArgumentOutOfRangeException(nameof(milliseconds), \"milliseconds 不能小于 0\");\n        }\n\n        return AddStep($\"Wait({milliseconds})\", _ => _services.Delay(milliseconds));\n    }\n\n    public async Task<BvPage> Run()\n    {\n        if (Interlocked.CompareExchange(ref _isRunning, 1, 0) != 0)\n        {\n            throw new InvalidOperationException(\"同一个 BvFlow 不能并发执行\");\n        }\n\n        try\n        {\n            BvFlowStep[] steps;\n            lock (_syncRoot)\n            {\n                _hasStarted = true;\n                steps = _steps.ToArray();\n            }\n\n            var context = new BvFlowExecutionContext();\n            for (var i = 0; i < steps.Length; i++)\n            {\n                var step = steps[i];\n                try\n                {\n                    _services.ThrowIfCancellationRequested();","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/Core/BgiVision/BvFlow.cs#L200-L236","documentation":"Thrown when the MsRdpClient10 ActiveX control's SecuredSettings2 property returns null via late-binding reflection. SecuredSettings2 is the IMsRdpClientSecuredSettings interface that exposes keyboard-hook mode and audio redirection settings. A null return means the ActiveX object exists but has not reached the state where secured settings are exposed — typically because the control has not been fully created or the RDP client version on this Windows installation does not support this interface.","triggerScenarios":"Called in ConnectToChildSession right after setting basic connection properties (Server, DesktopWidth, etc.) via GetComProperty(client, \"SecuredSettings2\"). Returns null when the AxHost has a window handle but the underlying COM object hasn't finished initializing its secured-settings interface, or on a Windows SKU where MsRdpClient10 is not registered.","commonSituations":"Windows version older than 10 (no MsRdpClient10 registered), RDP client components disabled or uninstalled, ActiveX initialization race condition where ConnectToChildSession is called too early, or the CLSID A0C63C30-F08D-4AB4-907C-34905D770C7D resolved to an older MsTscAx that lacks SecuredSettings2.","solutions":["Verify Windows 10 or later with RDP 8+ client installed (run mstsc /version).","Ensure ConnectToChildSession is called only after the WindowsFormsHost/AxHost control is loaded and visible (not in a collapsed/collapsed parent).","Register or repair the RDP ActiveX COM component (regsvr32 mstscax.dll).","Fall back to reading 'SecuredSettings' (older interface) if 'SecuredSettings2' is null, logging a diagnostic."],"exampleFix":"// before\nvar securedSettings = GetComProperty(client, \"SecuredSettings2\")\n    ?? throw new COMException(\"RDP ActiveX 未返回 SecuredSettings2。\");\n\n// after — fall back to legacy SecuredSettings\nvar securedSettings = GetComProperty(client, \"SecuredSettings2\")\n    ?? GetComProperty(client, \"SecuredSettings\");\nif (securedSettings is null)\n    throw new COMException(\"RDP ActiveX 未返回 SecuredSettings2，且旧版 SecuredSettings 也不可用。\");","handlingStrategy":"try-catch","validationCode":"// Check interface availability before calling ConnectToChildSession\nvar ocx = GetOcx();\nif (ocx is null) return; // control not ready\nvar hasSecuredSettings2 = ocx.GetType().InvokeMember(\n    \"SecuredSettings2\", BindingFlags.GetProperty, null, ocx, null) is not null;","typeGuard":"static bool SupportsSecuredSettings2(object client) =>\n    GetComProperty(client, \"SecuredSettings2\") is not null;","tryCatchPattern":"try\n{\n    var securedSettings = GetComProperty(client, \"SecuredSettings2\")\n        ?? GetComProperty(client, \"SecuredSettings\");\n}\ncatch (COMException ex) when (ex.ErrorCode == unchecked((int)0x80004005))\n{\n    // log and abort child-session connect with diagnostic\n}","preventionTips":["Verify the target machine runs Windows 10+ with RDP client 8+ before enabling child sessions.","Test SecuredSettings2/AdvancedSettings7 availability at startup and disable child-session features if missing.","Register mstscax.dll as part of deployment verification."],"tags":["rdp","com","activex","child-session","windows"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}