1

[我之前在 PowerShell Technet 论坛上发布过这个问题,但没有回复]

我正在尝试更改 Windows XP 快速启动设置(使用 PowerShell 启用/禁用它)。现有的 VBScript 解决方案依赖于 Registry 或 SendKeys,所以我认为这在 PowerShell 中通过 UIAutomation 是可行的。我的第一次尝试只是获取对表示需要更改的复选框的 AutomationElement 的引用(控制面板 -> 任务栏和开始菜单 -> 任务栏选项卡 -> 显示快速启动复选框)。这是脚本:

[void][System.Reflection.Assembly]::LoadWithPartialName("UIAutomationClient")
[void][System.Reflection.Assembly]::LoadWithPartialName("UIAutomationTypes")

$root = [Windows.Automation.AutomationElement]::RootElement

$condition1 = New-Object Windows.Automation.PropertyCondition([Windows.Automation.AutomationElement]::NameProperty, 'Taskbar and Start Menu Properties')
$properties = $root.FindFirst([Windows.Automation.TreeScope]::Descendants, $condition1)

$condition2 = New-Object Windows.Automation.PropertyCondition([Windows.Automation.AutomationElement]::NameProperty, 'Show Quick Launch')

$checkboxes = $properties.FindAll([Windows.Automation.TreeScope]::Descendants, $condition2)

foreach($checkbox in $checkboxes)
{
  $checkbox.Current.Name
  $checkbox.Current.ControlType.ProgrammaticName
}

脚本不会出错,但会返回意外结果:

显示快速启动

控件类型.窗格

脚本将 AutomationElement 视为 ControlType.Pane,而不是 ControlType.CheckBox。等效的(至少我是这么认为的)C# 控制台应用程序返回预期结果:

using System;
using System.Windows.Automation;

namespace ConsoleApplication1
{
  class Program
  {
    static void Main(string[] args)
    {
      AutomationElement root = AutomationElement.RootElement;
      AutomationElement properties = root.FindFirst(
        TreeScope.Descendants,
        new PropertyCondition(AutomationElement.NameProperty,
          "Taskbar and Start Menu Properties"));

      AutomationElementCollection checkboxes = properties.FindAll(
        TreeScope.Descendants,
        new PropertyCondition(AutomationElement.NameProperty,
          "Show Quick Launch"));

      foreach (AutomationElement checkbox in checkboxes)
      {
        Console.WriteLine(checkbox.Current.Name);
        Console.WriteLine(checkbox.Current.ControlType.ProgrammaticName);
      }
    }
  }
}

显示快速启动

ControlType.CheckBox

我究竟做错了什么?PowerShell 脚本从 ISE(所以 V2)执行,并且脚本和 C# 程序都假定小程序已经打开/可见。(XP SP3)

4

1 回答 1

1

基于Using WPF UI Automation with PowerShell (CodeProject)Problem Finding AutomationElement in PowerShell script (MSDN Forums)

  1. UI 自动化 API 仅适用于 STA 线程,而 PowerShell 始终运行脚本 MTA。解决方法是使用-sta开关运行 PowerShell 或从默认为 STA 的 PowerShell“集成脚本环境”(ISE) 中运行脚本。

  2. PowerShell 处理值类型有问题。解决方案是在脚本中插入一些内联 C# 代码以获取 UIAutomation 根元素。

工作代码:

[void] [Reflection.Assembly]::Load('UIAutomationClient, ' + 
    'Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35')
[void] [Reflection.Assembly]::Load('UIAutomationTypes, ' + 
    'Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35')
$source = @"
using System;
using System.Windows.Automation;
namespace UIAutTools
{
    public class Element
    {
        public static AutomationElement RootElement
        {
            get
            {
                return AutomationElement.RootElement;
            }
        }
    }
}
"@
Add-Type -TypeDefinition $source -ReferencedAssemblies( `
    "UIAutomationClient", "UIAutomationTypes")
$root = [UIAutTools.Element]::RootElement
$condition = New-Object Windows.Automation.PropertyCondition( `
    [Windows.Automation.AutomationElement]::NameProperty, `
    'start')
$startButton = $root.FindFirst( `
    [Windows.Automation.TreeScope]::Descendants, $condition)
$startButton.Current.Name
$startButton.Current.ControlType.ProgrammaticName
于 2010-10-25T09:50:03.403 回答