如何将FindAll()与nuget包Interop.UIAutomationClient一起使用

问题描述 投票:0回答:1

我想使用来自 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

c# windows com-interop microsoft-ui-automation
1个回答
1
投票

您不需要任何 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;
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.