PowerShell でRPA(UI Automation)を行う(UI Automation PowerShell Extensionsを使用しない)

2025年2月8日

電卓とメモ帳のサンプルです

inspect

要素を調べるツール

“C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\inspect.exe"

バッチファイル

PowerShell -Command "& (Invoke-Expression -Command ('{' + (((Get-Content %~f0 )[4..199]) | Out-String )+ '}'))" %*
timeout /t 55 & goto:eof

# 必要なアセンブリの読み込み
Add-Type -AssemblyName "UIAutomationClient"
Add-Type -AssemblyName "UIAutomationTypes"

# プロパティの変数化
$UIAElement = [System.Windows.Automation.AutomationElement]

$UIAPropertyCondition = [System.Windows.Automation.PropertyCondition]
$UIATreeScope = [System.Windows.Automation.TreeScope]
$UIAControlType = [System.Windows.Automation.ControlType]
$UIAInvokePattern = [System.Windows.Automation.InvokePattern]::Pattern

# 電卓の起動
$calcProcess = Start-Process -FilePath "calc.exe" -PassThru
Start-Sleep -s 2

# 電卓のメインウィンドウ取得
$cndCalcWindow = New-Object $UIAPropertyCondition($UIAElement::ClassNameProperty, "ApplicationFrameWindow")
$elmCalcWindow = $UIAElement::RootElement.FindFirst($UIATreeScope::Children, $cndCalcWindow)

if ($elmCalcWindow -eq $null) {
    Write-Host "電卓のメインウィンドウを取得できませんでした。"
    exit 1
}

# クリアボタンの押下
$cndClearButton = New-Object $UIAPropertyCondition($UIAElement::AutomationIdProperty, "clearButton")
$elmClearButton = $elmCalcWindow.FindFirst($UIATreeScope::Subtree, $cndClearButton)
$invokePattern = $elmClearButton.GetCurrentPattern($UIAInvokePattern)
$invokePattern.Invoke()

# 数字ボタンの押下
$numbers = "123456"
foreach ($number in $numbers.ToCharArray()) {
    $cndNumberButton = New-Object $UIAPropertyCondition($UIAElement::NameProperty, [string]$number)
    $elmNumberButton = $elmCalcWindow.FindFirst($UIATreeScope::Subtree, $cndNumberButton)
    $invokePattern = $elmNumberButton.GetCurrentPattern($UIAInvokePattern)
    $invokePattern.Invoke()
}

# 割り算ボタンの押下
$cndDivideButton = New-Object $UIAPropertyCondition($UIAElement::AutomationIdProperty, "divideButton")
$elmDivideButton = $elmCalcWindow.FindFirst($UIATreeScope::Subtree, $cndDivideButton)
$invokePattern = $elmDivideButton.GetCurrentPattern($UIAInvokePattern)
$invokePattern.Invoke()

# 5ボタンの押下
$cndFiveButton = New-Object $UIAPropertyCondition($UIAElement::NameProperty, "5")
$elmFiveButton = $elmCalcWindow.FindFirst($UIATreeScope::Subtree, $cndFiveButton)
$invokePattern = $elmFiveButton.GetCurrentPattern($UIAInvokePattern)
$invokePattern.Invoke()

# イコールボタンの押下
$cndEqualButton = New-Object $UIAPropertyCondition($UIAElement::AutomationIdProperty, "equalButton")
$elmEqualButton = $elmCalcWindow.FindFirst($UIATreeScope::Subtree, $cndEqualButton)
$invokePattern = $elmEqualButton.GetCurrentPattern($UIAInvokePattern)
$invokePattern.Invoke()

# 結果をクリップボードにコピー
$cndResult = New-Object $UIAPropertyCondition($UIAElement::AutomationIdProperty, "CalculatorResults")
$elmResult = $elmCalcWindow.FindFirst($UIATreeScope::Subtree, $cndResult)
$elmResult.SetFocus()
[System.Windows.Forms.SendKeys]::SendWait("^c")  # ^ = CTRL

# メモ帳の起動
$notepadProcess = Start-Process -FilePath "notepad.exe" -PassThru
Start-Sleep -s 2

# メモ帳のメインウィンドウ取得
$cndNotepadWindow = New-Object $UIAPropertyCondition($UIAElement::ClassNameProperty, "Notepad")
$elmNotepadWindow = $UIAElement::RootElement.FindFirst($UIATreeScope::Children, $cndNotepadWindow)

if ($elmNotepadWindow -eq $null) {
    Write-Host "メモ帳のメインウィンドウを取得できませんでした。"
    exit 1
}

# 結果をメモ帳に貼り付けClassName:	"RichEditD2DPT"


$cndRichEdit = New-Object $UIAPropertyCondition($UIAElement::ClassNameProperty, "RichEditD2DPT")
$elmRichEdit = $elmNotepadWindow.FindFirst($UIATreeScope::Subtree, $cndRichEdit)
$elmRichEdit.SetFocus()
[System.Windows.Forms.SendKeys]::SendWait("^v")  # ^ = CTRL

説明

コマンドライン部分

PowerShell -Command "& (Invoke-Expression -Command ('{' + (((Get-Content %~f0 )[4..199]) | Out-String )+ '}'))" %*
timeout /t 55 & goto:eof
  • PowerShell -Command "..." は、PowerShellスクリプトを実行するためのコマンドです。
  • Invoke-Expression を使って、指定したスクリプトを評価し、実行します。
  • Get-Content %~f0 は、スクリプトファイルの内容を取得するコマンドです。[4..199] は、5行目から200行目までを取得する部分です。
  • timeout /t 55 は、55秒間待機するコマンドです。
  • goto:eof は、スクリプトの終わりにジャンプするコマンドです。

必要なアセンブリの読み込み

Add-Type -AssemblyName "UIAutomationClient"
Add-Type -AssemblyName "UIAutomationTypes"
  • 必要なUI Automationのアセンブリをインポートしています。これにより、UIの操作が可能になります。

プロパティの変数化

$UIAElement = [System.Windows.Automation.AutomationElement]
$UIAPropertyCondition = [System.Windows.Automation.PropertyCondition]
$UIATreeScope = [System.Windows.Automation.TreeScope]
$UIAControlType = [System.Windows.Automation.ControlType]
$UIAInvokePattern = [System.Windows.Automation.InvokePattern]::Pattern
  • UI Automationで使用するプロパティと変数を定義しています。

電卓の起動

$calcProcess = Start-Process -FilePath "calc.exe" -PassThru
Start-Sleep -s 2
  • Start-Process コマンドで電卓を起動し、2秒間待機します。

電卓のメインウィンドウ取得

$cndCalcWindow = New-Object $UIAPropertyCondition($UIAElement::ClassNameProperty, "ApplicationFrameWindow")
$elmCalcWindow = $UIAElement::RootElement.FindFirst($UIATreeScope::Children, $cndCalcWindow)

if ($elmCalcWindow -eq $null) {
    Write-Host "電卓のメインウィンドウを取得できませんでした。"
    exit 1
}
  • 電卓のメインウィンドウを取得します。取得できない場合は、エラーメッセージを表示してスクリプトを終了します。

クリアボタンの押下

$cndClearButton = New-Object $UIAPropertyCondition($UIAElement::AutomationIdProperty, "clearButton")
$elmClearButton = $elmCalcWindow.FindFirst($UIATreeScope::Subtree, $cndClearButton)
$invokePattern = $elmClearButton.GetCurrentPattern($UIAInvokePattern)
$invokePattern.Invoke()
  • クリアボタンを取得し、そのボタンを押してクリアします。

数字ボタンの押下

$numbers = "123456"
foreach ($number in $numbers.ToCharArray()) {
    $cndNumberButton = New-Object $UIAPropertyCondition($UIAElement::NameProperty, [string]$number)
    $elmNumberButton = $elmCalcWindow.FindFirst($UIATreeScope::Subtree, $cndNumberButton)
    $invokePattern = $elmNumberButton.GetCurrentPattern($UIAInvokePattern)
    $invokePattern.Invoke()
}
  • 数字のボタンを一つずつ取得し、そのボタンを押していきます。

割り算ボタンの押下

$cndDivideButton = New-Object $UIAPropertyCondition($UIAElement::AutomationIdProperty, "divideButton")
$elmDivideButton = $elmCalcWindow.FindFirst($UIATreeScope::Subtree, $cndDivideButton)
$invokePattern = $elmDivideButton.GetCurrentPattern($UIAInvokePattern)
$invokePattern.Invoke()
  • 割り算ボタンを取得し、そのボタンを押します。

5ボタンの押下

$cndFiveButton = New-Object $UIAPropertyCondition($UIAElement::NameProperty, "5")
$elmFiveButton = $elmCalcWindow.FindFirst($UIATreeScope::Subtree, $cndFiveButton)
$invokePattern = $elmFiveButton.GetCurrentPattern($UIAInvokePattern)
$invokePattern.Invoke()
  • 5のボタンを取得し、そのボタンを押します。

イコールボタンの押下

$cndEqualButton = New-Object $UIAPropertyCondition($UIAElement::AutomationIdProperty, "equalButton")
$elmEqualButton = $elmCalcWindow.FindFirst($UIATreeScope::Subtree, $cndEqualButton)
$invokePattern = $elmEqualButton.GetCurrentPattern($UIAInvokePattern)
$invokePattern.Invoke()
  • イコールボタンを取得し、そのボタンを押します。

結果をクリップボードにコピー

$cndResult = New-Object $UIAPropertyCondition($UIAElement::AutomationIdProperty, "CalculatorResults")
$elmResult = $elmCalcWindow.FindFirst($UIATreeScope::Subtree, $cndResult)
$elmResult.SetFocus()
[System.Windows.Forms.SendKeys]::SendWait("^c")  # ^ = CTRL
  • 計算結果を取得し、クリップボードにコピーします。

メモ帳の起動

$notepadProcess = Start-Process -FilePath "notepad.exe" -PassThru
Start-Sleep -s 2
  • Start-Process コマンドでメモ帳を起動し、2秒間待機します。

メモ帳のメインウィンドウ取得

$cndNotepadWindow = New-Object $UIAPropertyCondition($UIAElement::ClassNameProperty, "Notepad")
$elmNotepadWindow = $UIAElement::RootElement.FindFirst($UIATreeScope::Children, $cndNotepadWindow)

if ($elmNotepadWindow -eq $null) {
    Write-Host "メモ帳のメインウィンドウを取得できませんでした。"
    exit 1
}
  • メモ帳のメインウィンドウを取得します。取得できない場合は、エラーメッセージを表示してスクリプトを終了します。

結果をメモ帳に貼り付け

$cndRichEdit = New-Object $UIAPropertyCondition($UIAElement::ClassNameProperty, "RichEditD2DPT")
$elmRichEdit = $elmNotepadWindow.FindFirst($UIATreeScope::Subtree, $cndRichEdit)
$elmRichEdit.SetFocus()
[System.Windows.Forms.SendKeys]::SendWait("^v")  # ^ = CTRL
  • メモ帳のリッチエディットボックスを取得し、計算結果を貼り付けます。

bat,PowerShell ,windows

Posted by eightban