如何从 PowerShell 使用非托管 UI 自动化 API

anq*_*qie 5 com dll powershell ui-automation microsoft-ui-automation

Windows 的 UI 自动化 API 可通过两个 DLL 获得。一种是托管 DLL,即C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\UIAutomationClient.dll. 另一种是非托管 DLL,即C:\Windows\System32\UIAutomationCore.dll. 根据这篇文章,非托管 API 在可见元素数量方面优于托管 API,因此我想使用非托管 API。

我尝试了三种方法,但都失败了。你能告诉我正确的做法吗?

方法#1:新对象 -ComObject

$uia = New-Object -ComObject <ProgID of CUIAutomation>
$root = $uia.GetRootElement()
Run Code Online (Sandbox Code Playgroud)

失败,因为New-Object需要 ProgID 但CUIAutomation没有 ProgID。

方法#2:从 CLSID 实例化

的 CLSIDCUIAutomationff48dba4-60ef-4201-aa87-54103eef594e,那么,

$type = [Type]::GetTypeFromCLSID("ff48dba4-60ef-4201-aa87-54103eef594e")
$uia = [Activator]::CreateInstance($type)
$root = $uia.GetRootElement()
Run Code Online (Sandbox Code Playgroud)

但失败并出现以下错误消息。我还是不知道为什么。

Method invocation failed because [System.__ComObject] does not contain a method named 'GetRootElement'.
At line:1 char:1
+ $root = $uia.GetRootElement()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound
Run Code Online (Sandbox Code Playgroud)

方法#3:添加类型

Add-Type -Path "C:\Windows\System32\UIAutomationCore.dll"
$uia = New-Object UIAutomationClient.CUIAutomation
$root = $uia.GetRootElement()
Run Code Online (Sandbox Code Playgroud)

失败,因为Add-Type需要托管 DLL。

错误信息:

Add-Type : Could not load file or assembly 'file:///C:\Windows\System32\UIAutomationCore.dll' or one of its dependencies. The module was expected to contain an assembly manifest. At line:1 char:1
+ Add-Type -Path "C:\Windows\System32\UIAutomationCore.dll"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Add-Type], BadImageFormatException
    + FullyQualifiedErrorId : System.BadImageFormatException,Microsoft.PowerShell.Commands.AddTypeCommand
Run Code Online (Sandbox Code Playgroud)

编辑 (2018-06-12)

我尝试了另一种方法。(并且失败了)

方法#4:互操作 DLL

我不太明白 Interop DLL 到底是什么,但这篇文章说 Interop DLL 无论如何都对 OP 有所帮助。我安装了 Visual Studio 并Interop.UIAutomationClient.dll按照帖子中的过程生成。

Add-Type -Path "Interop.UIAutomationClient.dll"
$uia = New-Object UIAutomationClient.CUIAutomationClass
$root = $uia.GetRootElement()
$children = $root.FindAll([UIAutomationClient.TreeScope]::TreeScope_Children, $uia.CreateTrueCondition())
Run Code Online (Sandbox Code Playgroud)

我成功获取了$root,但在 行失败$children并出现以下错误消息。

Method invocation failed because [System.__ComObject] does not contain a method named 'FindAll'.
At line:1 char:1
+ $children = $root.FindAll([UIAutomationClient.TreeScope]::TreeScope_C ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound
Run Code Online (Sandbox Code Playgroud)

我还是不知道为什么。

anq*_*qie 0

我还没有解决这个问题,但终于找到了替代方案,那就是C# Interactive。我会将这个问题留给 PowerShell 用户,但是,如果您可以使用 C# Interactive 作为 PowerShell 的替代方案,以下部分可能会对您有所帮助。

方法#5:C# 交互

  1. 安装 Visual Studio。
  2. Interop.UIAutomationClient.dll按照本文的步骤生成。
  3. 在 上运行以下脚本csi.exe
#r "Interop.UIAutomationClient.dll"
var uia = new UIAutomationClient.CUIAutomation();
var root = uia.GetRootElement();
var children = root.FindAll(UIAutomationClient.TreeScope.TreeScope_Children, uia.CreateTrueCondition());
Run Code Online (Sandbox Code Playgroud)

仅供参考,如果同一文件夹中仅存在以下文件,C# Interactive 即可工作(即,只需从开发环境中引入以下文件即可在任何地方使用 C# Interactive)。

  • C:\Program Files (x86)\MSBuild\14.0\Bin\csi.exe
  • C:\Program Files (x86)\MSBuild\14.0\Bin\csi.rsp
  • C:\Program Files (x86)\MSBuild\14.0\Bin\Microsoft.CodeAnalysis.CSharp.dll
  • C:\Program Files (x86)\MSBuild\14.0\Bin\Microsoft.CodeAnalysis.CSharp.Scripting.dll
  • C:\Program Files (x86)\MSBuild\14.0\Bin\Microsoft.CodeAnalysis.dll
  • C:\Program Files (x86)\MSBuild\14.0\Bin\Microsoft.CodeAnalysis.Scripting.dll
  • C:\Program Files (x86)\MSBuild\14.0\Bin\System.AppContext.dll
  • C:\Program Files (x86)\MSBuild\14.0\Bin\System.Collections.Immutable.dll
  • C:\Program Files (x86)\MSBuild\14.0\Bin\System.Diagnostics.StackTrace.dll
  • C:\Program Files (x86)\MSBuild\14.0\Bin\System.IO.FileSystem.dll
  • C:\Program Files (x86)\MSBuild\14.0\Bin\System.Reflection.Metadata.dll