UI 自动化 - 模态对话框可防止自动化

问题描述

我正在自动一个应用程序,当自动化使用 Select 时,会打开一个模式对话框,阻止自动化继续。我已经看到这个问题在几个地方讨论过,并提出了一些建议。我已经尝试了所有的建议,但都没有成功。为了发布这个问题,我整理了一个展示相同问题的小应用程序。该应用程序包含一个列表框和一个按钮。当列表框项目选择更改时,它会打开一个消息框。该按钮启动一个自动化序列运行,它选择第一个项目,然后尝试通过按 OK 按钮关闭对话框。

自动化序列在非 UI MTA 线程(任务)中运行。因为 Select 块,它是从另一个非 UI MTA 线程(任务)调用的。当主自动化序列在启动 Select 任务后继续运行时,它会在尝试查找弹出的对话框时挂起。

我看到了添加 WindowOpenedEvent 处理程序并从那里按下 OK 按钮的建议。我已将其包含在此应用程序中,但从未调用处理程序。在我的实际应用程序中,所有其他对话框都会调用处理程序,直到从 Select 调用中打开一个

关于如何从自动化序列中消除此对话框,还有其他想法吗?

C# .Net 框架 4.8

MainWindow.xaml.cs:

     using System;
     using System.Diagnostics;
     using System.Threading.Tasks;
     using System.Windows;
     using System.Windows.Automation;
     using System.Windows.Controls;
     using System.Windows.Interop;
        
     namespace AutomationSelectTest
     {
         /// <summary>
         /// Interaction logic for MainWindow.xaml
         /// </summary>
         public partial class MainWindow : Window
         {
             private Task _task;
        
             public MainWindow()
             {
                 InitializeComponent();
             }
        
             private void ListBox_SelectionChanged(object sender,SelectionChangedEventArgs e)
             {
                 MessageBox.Show("Selection changed");
             }
        
             private void Button_Click(object sender,RoutedEventArgs e)
             {
                 var windowHandle = new WindowInteropHelper(this).Handle;
                 _task = Task.Factory.StartNew(() => AutomationSequence(windowHandle));
             }
        
             private static readonly System.Windows.Automation.Condition ButtonOkCondition = new AndCondition(
                 new PropertyCondition(AutomationElement.ClassNameProperty,"Button"),new PropertyCondition(AutomationElement.NameProperty,"OK"));
        
             private static void AutomationSequence(IntPtr windowHandle)
             {
                 var application = AutomationElement.FromHandle(windowHandle);
                 Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent,application,TreeScope.Subtree,Window_Opened);
                 var listBoxItem = application.FindFirst(TreeScope.Descendants,new PropertyCondition(AutomationElement.ClassNameProperty,"ListBoxItem"));
                 var listBoxSelectionItemPattern = listBoxItem.GetCurrentPattern(SelectionItemPattern.Pattern) as SelectionItemPattern ?? throw new InvalidOperationException();
                 // Because the call to Select will block,run it as a separate task
                 var selectionTask = Task.Factory.StartNew(() => listBoxSelectionItemPattern.Select());
                 var dialog = application.FindFirst(TreeScope.Children,new PropertyCondition(AutomationElement.LocalizedControlTypeProperty,"Dialog"));
                 var buttonOk = dialog.FindFirst(TreeScope.Subtree,ButtonOkCondition);
                 var buttonOkInvokePattern = buttonOk.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern ?? throw new InvalidOperationException();
                 buttonOkInvokePattern.Invoke();
                 // Now wait for the Select to return
                 selectionTask.Wait();
                 Automation.RemoveAutomationEventHandler(WindowPattern.WindowOpenedEvent,Window_Opened);
             }
        
             private static void Window_Opened(object sender,AutomationEventArgs e)
             {
                 // Never gets here
                 Debugger.Break();
             }
         }
     }

MainWindow.xaml:

 <Window x:Class="AutomationSelectTest.MainWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:local="clr-namespace:AutomationSelectTest"
         mc:Ignorable="d"
         Title="MainWindow" Height="450" Width="800">
     <Grid>
         <ListBox HorizontalAlignment="Left" Height="144" Margin="10,10,0" VerticalAlignment="Top" Width="151" SelectionChanged="ListBox_SelectionChanged">
             <ListBoxItem Content="ListBoxItem1"/>
             <ListBoxItem Content="ListBoxItem2"/>
             <ListBoxItem Content="ListBoxItem3"/>
         </ListBox>
         <Button Content="Run Automation" HorizontalAlignment="Left" Height="39" Margin="10,159,0" VerticalAlignment="Top" Width="151" Click="Button_Click"/>
    
         </Grid>
     </Window>

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)