1

[この質問は以前にPowerShellTechnetフォーラムに投稿しましたが、回答はありません]

Windows XPのクイック起動設定を変更しようとしています(PowerShellを使用して有効/無効にします)。既存のVBScriptソリューションはレジストリまたはSendKeysのいずれかに依存しているため、これはUIAutomationを介してPowerShellで実行可能であると思いました。私の最初の試みは、変更が必要なチェックボックスを表す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
}

スクリプトはエラーになりませんが、予期しない結果を返します。

クイック起動を表示

ControlType.Pane

ControlType.CheckBoxの代わりに、スクリプトはAutomationElementをControlType.Paneとして認識します。同等の(少なくとも私はそう思う)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

PowerShellでのWPFUIオートメーションの使用(CodeProject)およびPowerShellスクリプトでのAutomationElementの検出の問題(MSDNフォーラム)に基づく:

  1. UIオートメーションAPIはSTAスレッドからのみ機能し、PowerShellは常にスクリプトMTAを実行します。これを回避するには、-staスイッチを使用してPowerShellを実行するか、PowerShellの「統合スクリプト環境」(ISE)内からスクリプトを実行します。デフォルトはSTAです。

  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 に答える