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

如何使用PowerShell中的非托管UI自动化API,powershell,dll,com,ui-automation,microsoft-ui-automation,Powershell,Dll,Com,Ui Automation,Microsoft Ui Automation,Windows的UI自动化API可从两个DLL获得。 一个是托管DLL,它是C:\ProgramFiles\Reference Assembly\Microsoft\Framework\v3.0\UIAutomationClient.DLL。 另一个是非托管DLL,即C:\Windows\System32\UIAutomationCore.DLL。 根据,非托管API在可见元素数量方面优于托管API,因此我希望使用非托管API 我尝试了三种方法,但都失败了。 你能告诉我正确的方法吗 方法#1:新

Windows的UI自动化API可从两个DLL获得。 一个是托管DLL,它是
C:\ProgramFiles\Reference Assembly\Microsoft\Framework\v3.0\UIAutomationClient.DLL
。 另一个是非托管DLL,即
C:\Windows\System32\UIAutomationCore.DLL
。 根据,非托管API在可见元素数量方面优于托管API,因此我希望使用非托管API

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

方法#1:新对象-共对象
$uia=新对象-共对象
$root=$uia.GetRootElement()
失败,因为新对象需要ProgID,但没有ProgID

方法2:从CLSID实例化
CUIAutomation
的CLSID为
ff48dba4-60ef-4201-aa87-54103eef594e
,然后

$type=[type]::GetTypeFromCLSID(“ff48dba4-60ef-4201-aa87-54103eef594e”)
$uia=[Activator]::CreateInstance($type)
$root=$uia.GetRootElement()
但失败,并显示以下错误消息。 我仍然不知道为什么

方法调用失败,因为[System.\uuu-ComObject]不包含名为“GetRootElement”的方法。
第1行字符:1
+$root=$uia.GetRootElement()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+CategoryInfo:InvalidOperation:(:)[],运行时异常
+FullyQualifiedErrorId:MethodNotFound
方法#3:添加类型
添加类型-路径“C:\Windows\System32\UIAutomationCore.dll”
$uia=新对象UIAutomationClient.CUIAutomation
$root=$uia.GetRootElement()
失败,因为
添加类型
需要托管DLL

错误消息:

添加类型:无法加载文件或程序集'file:///C:\Windows\System32\UIAutomationCore.dll'或其依赖项之一。模块应包含程序集清单。第1行字符:1
+添加类型-路径“C:\Windows\System32\UIAutomationCore.dll”
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+CategoryInfo:NotSpecified:(:)[Add Type],BadImageFormatException
+FullyQualifiedErrorId:System.BadImageFormatException,Microsoft.PowerShell.Commands.AddTypeCommand
编辑(2018-06-12) 我尝试了另一种方法。(但失败了)

方法4:互操作DLL 我真的不太明白互操作DLL到底是什么,但说互操作DLL帮助了操作。 我安装了VisualStudio,并按照本文的过程生成了
Interop.UIAutomationClient.dll

添加类型-路径“Interop.UIAutomationClient.dll”
$uia=新对象UIAutomationClient.CUIAutomationClass
$root=$uia.GetRootElement()
$children=$root.FindAll([UIAutomationClient.TreeScope]::TreeScope\u children,$uia.CreateTrueCondition())
我成功地获取了
$root
,但在
$children
行失败,并显示以下错误消息

方法调用失败,因为[System.\uuu-CoObject]不包含名为“FindAll”的方法。
第1行字符:1
+$children=$root.FindAll([UIAutomationClient.TreeScope]::TreeScope\u C。。。
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+CategoryInfo:InvalidOperation:(:)[],运行时异常
+FullyQualifiedErrorId:MethodNotFound

我仍然不知道为什么。

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

方法#5:C#交互式
  • 安装VisualStudio
  • 按照的过程生成
    Interop.UIAutomationClient.dll
  • 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());
    
    仅供参考,如果同一文件夹中只存在以下文件,C#Interactive就可以工作(即,您可以在任何地方使用C#Interactive,只需从开发环境中取出以下文件即可)

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

    方法2您应该到达

    IID_IUIAutomation = "{30CBE57D-D9D0-452A-AB13-7AC5AC4825EE}"
    
    CLSID_UIAutomationClient = "{944DE083-8FB8-45CF-BCB7-C477ACB2F897}"
    ;CoClasses
    CLSID_CUIAutomation = "{FF48DBA4-60EF-4201-AA87-54103EEF594E}"
    
    MS Doc表示

    备注

    每个UI Automation客户端应用程序都必须获得CUI Automation对象的此接口,才能访问UI Automation的功能

    下面的示例函数创建CUIAutomation对象并获取 IUIAutomation接口

    IUIAutomation *g_pAutomation; 
    
    BOOL InitializeUIAutomation() 
    { 
    CoInitialize(NULL); 
    HRESULT hr = CoCreateInstance(__uuidof(CUIAutomation), NULL, CLSCTX_INPROC_SERVER,  
        __uuidof(IUIAutomation), (void**)&g_pAutomation); 
    return (SUCCEEDED(hr)); 
    } 
    
    我无法让它在PS中工作,但也许这个答案在一定程度上有助于正确的方向(我让它在AutoIt中工作,但它的工作方式不同,你可以在google上的AutoIt IUIAutomation中找到它)

    两个人都跑,但当我醒来时

    $rootEl = $objCUI.GetType().InvokeMember(
    "GetRootElement", 
    "InvokeMethod", 
    $Null, 
    $objCUI, 
    @()
    )  
    
    我明白了
    $Type = [Type]::GetTypeFromCLSID('30CBE57D-D9D0-452A-AB13-7AC5AC4825EE')
    $objCUI = [System.Activator]::CreateInstance($Type)
    
    $rootEl = $objCUI.GetType().InvokeMember(
    "GetRootElement", 
    "InvokeMethod", 
    $Null, 
    $objCUI, 
    @()
    )  
    
    Add-Type -AssemblyName 'UIAutomationClient'
    $ae = [System.Windows.Automation.AutomationElement]
    $cTrue = [System.Windows.Automation.PropertyCondition]::TrueCondition
    $root = $ae::RootElement
    $winNames = $root.FindAll("Children", $cTrue).current.name