如何使用PowerShell

时间:2018-06-11 08:08:28

标签: powershell dll com ui-automation microsoft-ui-automation

适用于Windows的UI Automation API可从两个DLL中获得。 一个是托管DLL,C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\UIAutomationClient.dll。 另一个是非托管DLL,C:\Windows\System32\UIAutomationCore.dll。 根据{{​​3}},非托管API在可见元素数量方面优于托管API,因此我想使用非托管API。

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

方法#1:New-Object -ComObject

$uia = New-Object -ComObject <ProgID of CUIAutomation>
$root = $uia.GetRootElement()

失败,因为New-Object需要ProgID但this post没有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()

但因以下错误消息而失败。 我还是不知道为什么。

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

方法#3:添加类型

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

失败,因为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

编辑(2018-06-12)

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

方法#4:互操作DLL

我真的不明白Interop DLL到底是什么,但是CUIAutomation说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())

我成功获得$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

我仍然不知道为什么。

3 个答案:

答案 0 :(得分:0)

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

方法#5:C#Interactive

  1. 安装Visual Studio。
  2. 按照this post
  3. 的程序生成Interop.UIAutomationClient.dll
  4. csi.exe上运行以下脚本。
  5. #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:\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

答案 1 :(得分:0)

方法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自动化客户端应用程序都必须获得CUIAutomation对象的此接口,才能访问UI自动化的功能。

以下示例函数创建一个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找到它

$objCUI=[System.Runtime.InteropServices.Marshal]::GetTypeFromCLSID("30CBE57D-D9D0-452A-AB13-7AC5AC4825EE")

$Type = [Type]::GetTypeFromCLSID('30CBE57D-D9D0-452A-AB13-7AC5AC4825EE')
$objCUI = [System.Activator]::CreateInstance($Type)

都跑了,但是我来

$rootEl = $objCUI.GetType().InvokeMember(
"GetRootElement", 
"InvokeMethod", 
$Null, 
$objCUI, 
@()
)  

我遇到错误

答案 2 :(得分:0)

那呢?

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