using FlaUI.Core.AutomationElements; using FlaUI.Core.Definitions; using WxAgent.Core; namespace WxAgent.Windows; public sealed record WechatRecoveryCheck(string State, bool TransitionObserved, bool SameInstance, bool MainViewFound, bool SessionsFound, bool MessagesFound); public static partial class WechatChatClient { public static async Task> RecoverySmokeAsync(CancellationToken cancellationToken) { var checks = new List(); foreach (var state in new[] { "minimized", "tray-hidden" }) { var identity = await WithMainWindowAsync(async (main, _) => { await OpenFileTransferAssistantCoreAsync(main, cancellationToken).ConfigureAwait(false); var native = main.Properties.NativeWindowHandle.Value; var processId = main.Properties.ProcessId.Value; if (state == "minimized") main.AsWindow().Patterns.Window.Pattern.SetWindowVisualState(WindowVisualState.Minimized); else main.AsWindow().Close(); // Normal WeChat close-to-tray, not SW_HIDE or process termination. return (Handle: native.ToInt64(), ProcessId: processId); }, cancellationToken).ConfigureAwait(false); var transitioned = false; for (var attempt = 0; attempt < 30; attempt++) { var native = WechatNativeWindow.Enumerate().FirstOrDefault(window => window.Handle == identity.Handle && window.ProcessId == identity.ProcessId); transitioned = native is not null && (state == "minimized" ? native.Minimized : !native.Visible); if (transitioned) break; await Task.Delay(100, cancellationToken).ConfigureAwait(false); } await RecoverUiAsync(cancellationToken).ConfigureAwait(false); checks.Add(await WithMainWindowAsync((main, _) => Task.FromResult(new WechatRecoveryCheck( state, transitioned, main.Properties.NativeWindowHandle.Value.ToInt64() == identity.Handle && main.Properties.ProcessId.Value == identity.ProcessId, FindByAutomationId(main, WechatLocators.MainView) is not null, FindByAutomationId(main, WechatLocators.SessionList) is not null, FindByAutomationId(main, WechatLocators.MessageList) is not null)), cancellationToken).ConfigureAwait(false)); } return checks; } }