API автоматизации пользовательского интерфейса для Windows доступен из двух библиотек DLL. Одна из них — это управляемая DLL, которая называется C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\UIAutomationClient.dll
. Другая — неуправляемая DLL, которая называется C:\Windows\System32\UIAutomationCore.dll
. Согласно это сообщение, неуправляемый API превосходит управляемый API с точки зрения количества видимых элементов, поэтому я хотел бы использовать неуправляемый API .
Я пробовал три подхода, но все они потерпели неудачу. Подскажите правильный подход?
Подход №1: New-Object -ComObject
$uia = New-Object -ComObject <ProgID of CUIAutomation>
$root = $uia.GetRootElement()
Ошибка, поскольку New-Object
требует ProgID, но CUIAutomation
не имеет ProgID.
Подход № 2: создание экземпляров из CLSID
CLSID CUIAutomation
равен 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
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: Interop DLL
Я не совсем понимаю, что такое Interop DLL, но powershell-cmdlets-for-managing-windows-updates-via-wuapilib#8041782c-9c37-4f3e-a7e7-819a41379809" rel="nofollow noreferrer">в этом посте говорится, что DLL Interop все равно помогла 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
Я до сих пор не знаю, почему.
FindAll
, похоже, вам нужно преобразование типов.$root
— это объект базового класса, а не объект AutomationElement. - person Vasily Ryabov   schedule 12.06.2018[UIAutomationClient.IUIAutomationElement]($root)
не работает сConvertToFinalInvalidCastException
, посколькуIUIAutomationElement
несовместим с типом$root
, то естьSystem.__ComObject
. Во-первых, почемуGetRootElement
возвращаетSystem.__ComObject
, а неIUIAutomationElement
? - person anqooqie   schedule 14.06.2018