我想使用来自 C# 的 Microsoft UIAutomation。
我收集了一些在互联网上找到的内容,最终得到了以下代码(使用 Nuget 包“Interop.UIAutomationClient”版本=“10.19041.0”。)
using System;
using UIA = Interop.UIAutomationClient;
namespace TestUIA
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Starting...");
UIA.IUIAutomation NativeAutomation = new UIA.CUIAutomation8();
var Desktop = NativeAutomation.GetRootElement();
Console.WriteLine("Destop name is {0}", Desktop.CurrentName);
Console.WriteLine("Ending...");
}
}
}
效果很好! 我的 Windows 11 22H2 上的实际结果是
现在我想枚举桌面子项。我知道我必须使用
FindAll
方法。
不幸的是,我只能对第一个参数进行编码,如
Desktop.FindAll( UIA.TreeScope.TreeScope_Children,
但我不知道如何编写第二个论点...如果我使用 C++,我会使用
IUIAutomation::CreateTrueCondition
...
问题:如何在 C# 中使用 Nuget 包“Interop.UIAutomationClient”将“真实条件”传递给
FindAll
?
您不需要任何 nuget,只需从 Windows 引用 UIAutomationClient COM dll 作为 COM 对象即可:
现在,要创建真实条件,正如您所说,您必须使用 IUIAutomation::CreateTrueCondition 方法,该方法是在...CUIAutomation8(根类,它实现
IUIAutomation
)上实现的。我编写了一些扩展方法以使其更容易:
using System;
using System.Collections.Generic;
using System.Linq;
using UIAutomationClient;
static void Main()
{
Console.WriteLine("Starting...");
var desktop = UIAUtilities.Automation.GetRootElement();
Console.WriteLine("Destop name is {0}", desktop.CurrentName);
foreach (var element in desktop.EnumerateAll(TreeScope.TreeScope_Children))
{
Console.WriteLine(element.CurrentName);
}
Console.WriteLine("Ending...");
}
public static class UIAUtilities
{
private static readonly Lazy<CUIAutomation8> _automation = new(() => new CUIAutomation8());
public static CUIAutomation8 Automation => _automation.Value;
public static IEnumerable<IUIAutomationElement> EnumerateAll(this IUIAutomationElement element, TreeScope scope = TreeScope.TreeScope_Children, IUIAutomationCondition condition = null)
{
if (element == null)
return Enumerable.Empty<IUIAutomationElement>();
condition ??= Automation.CreateTrueCondition();
return ForEach(element.FindAll(scope, condition));
}
public static IEnumerable<IUIAutomationElement> ForEach(this IUIAutomationElementArray array)
{
if (array == null)
yield break;
for (var i = 0; i < array.Length; i++)
{
var element = array.GetElement(i);
if (element != null)
yield return element;
}
}
}