参考:
https://docs.microsoft.com/en-us/dotnet/framework/ui-automation/ui-automation-overview (没怎么看)
https://www.codeproject.com/Articles/141842/Automate-your-UI-using-Microsoft-Automation-Framew
(里面的示例工程代码可以下载,代码是一个test project。如果转project失败,可自己再建一个,将代码和xml文件重新导入,注意要将xml文件属性改成"Embedded Resource"。另外注意GetManifestResourceStream()函数里资源的命名空间。
简单概括:
- 支持自动化UI测试
- 可以操控第三方软件
对WPF来说,所有控件是通过实现抽象类AutomationPeer来实现的。每个AutomationPeer都会实现 “standard control patterns”。就是利用这些Pattern来"Invoke", "Select item", "Get Value", “Expand Collapse”等操作。这些Pattern是固定的,不能自定义。操作系统只支持这些Pattern。
步骤:
1. 先找控件:一般通过名字去找。
如何得知到名字呢? 使用Inspect.exe!。 vs装好后,就会有此文件。
_calculatorProcess = Process.Start("Calc.exe");
_calculatorAutomationElement = AutomationElement.RootElement.FindFirst
(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty,
"Calculator"));
public AutomationElement GetFunctionButton(string functionName)
{
AutomationElement functionButton = _calculatorAutomationElement.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, functionName));
if (functionButton == null)
{
throw new InvalidOperationException("No function button found with name: " + functionName);
}
return functionButton;
}
2, 找到控件想执行的pattern,找到后再执行。例如下面执行的Invoke操作
public InvokePattern GetInvokePattern(AutomationElement element)
{
return element.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
}
GetInvokePattern(GetFunctionButton(Functions.Clear)).Invoke();
在sample代码中还有菜单展开,执行的操作是ExpandCollapsePattern。
private ExpandCollapsePattern FindMenu(CalculatorMenu menu)
{
AutomationElement menuElement = _calculatorAutomationElement.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, menu.ToString()));
ExpandCollapsePattern expPattern = menuElement.GetCurrentPattern(ExpandCollapsePattern.Pattern) as ExpandCollapsePattern;
return expPattern;
}
在WPF中,如果控件不使用x:Name属性,很难找到该控件。如果使用,Name的值会自动设置到AutomationProperties.AutomationId,然后可用AutomationProperties.AutomationId找到该控件。当然也可以像下面这样,两个属性都指定。
<TextBox Text="{Binding Telephone}" x:Name="See_My_Name" AutomationProperties.AutomationId="See My AutomationId!"/>