適材適所

WindowsやPowerShellやネットワーク、IBMなどのシステム系の話やポイ活など気になったことも載せているブログです。

【UI Automation,PowerShell】ウィンドウを移動・サイズを変更する最も簡単なプログラム

Microsoft UI Automationを使うとWindowsのアプリケーション操作を自動化することができます。

ユーザーインターフェースの自動テストやRPAアプリケーションで使用されていますが、Windowsに標準で搭載されているコンソールアプリケーションであるPowerShellを使えば

誰でも簡単にその機能を使うことができます。

今回は、そのUIAutomationとPowerShellを使ってウィンドウの大きさ・位置を変える最も簡単なプログラムを紹介したいと思います。

っと、難しいことは置いておいて、

・RPA的なことを自前でやってみたい人

・デュアルディスプレイでウィンドウがどこかへ消えてしまって困っている人

・よくわからないけど自動でウィンドウを動かしてみたい人

等など、ここで紹介するプログラムを使ってウィンドウを動かしてみましょう!

環境

PS C:\> Get-WmiObject Win32_OperatingSystem|select version
version
-------
10.0.18362
PS C:\> ($PSVersionTable).PSVersion
MajorMinorBuildRevision
-----------------------
5118362145

PowerShellを起動する

Windowsのスタートメニューの中にあるPowerShellを起動します。

f:id:shinmai_papa:20210719130939p:plain

コードを貼りつける

 
#操作したいウィンドウのタイトル
$MAIN_WINDOW_TITLE='chrome'
#ウィンドウの新しい幅 (ピクセル単位)
$width=1000
#ウィンドウの新しい高さ (ピクセル単位)。
$heigh=1000
#コントロールの左側の絶対画面座標。
$x=0
#コントロールの上部の絶対画面座標。
$y=0
Add-Type -AssemblyName UIAutomationClient
#検索をデスクトップから開始するためデスクトップを取得する
$root= [System.Windows.Automation.AutomationElement]::RootElement
#検索対象は子要素だけとする
$scope=[System.Windows.Automation.TreeScope]::Children
#とりあえずGet-Processで取得できた一つ目のハンドルを対象とする。
$hwnd=(Get-Process |?{$_.MainWindowTitle -match $MAIN_WINDOW_TITLE})[0].MainWindowHandle
#ハンドルからウィンドウを取得する
$window=[System.Windows.Automation.AutomationElement]::FromHandle($hwnd)
#ウィンドウサイズの状態を把握するためにWindowPatternを使う
$windowPattern=$window.GetCurrentPattern([System.Windows.Automation.WindowPattern]::Pattern)
#ウィンドウサイズを変更する準備としてサイズを通常に変更する
$windowPattern.SetWindowVisualState([System.Windows.Automation.WindowVisualState]::Normal)
#ウィンドウサイズを変更するためのパターン。
$transformPattern=$window.GetCurrentPattern([System.Windows.Automation.TransformPattern]::Pattern)
#Maximamだと移動もサイズ変更もできないので注意。
$transformPattern.Resize($width,$heigh)
$transformPattern.Move($x,$y)

操作したいウィンドウのタイトルと変更後の幅、高さ、横座標、縦座標を設定する

上記の例では、ウィンドウのタイトルにchromeと入っているものを、

縦横 1000ピクセルのサイズに変更し、座標(0,0)、つまり左上に移動しています。

それらの設定は、コードの最初のところで設定しています。

#操作したいウィンドウのタイトル
$MAIN_WINDOW_TITLE='chrome'
#ウィンドウの新しい幅 (ピクセル単位)
$width=1000
#ウィンドウの新しい高さ (ピクセル単位)
$heigh=1000
#コントロールの左側の絶対画面座標
$x=0
#コントロールの上部の絶対画面座標
$y=0

ここでchromeを設定しています。

$MAIN_WINDOW_TITLE='chrome'

ここを操作したいウィンドウのタイトルに含まれる言葉に変更します。

ここではウィンドウの新しい幅と高さを指定します。

#ウィンドウの新しい幅 (ピクセル単位)
$width=1000
#ウィンドウの新しい高さ (ピクセル単位)
$heigh=1000

1000のところを任意の数字に変更します。

ここではウィンドウの座標をx,yで設定します。

#コントロールの左側の絶対画面座標
$x=0
#コントロールの上部の絶対画面座標
$y=0

0となっているところを変更することで、任意の位置にウィンドウを移動することができます。

すべて設定できたら、エンターを押します。

エラーが出たら

「null 配列にインデックスを付けることはできません。」が出た

null 配列にインデックスを付けることはできません。
発生場所 行:13 文字:1
+ $hwnd=(Get-Process |?{$_.MainWindowTitle -match $MAIN_WINDOW_TITLE})[ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo: InvalidOperation: (:) []、RuntimeException
+ FullyQualifiedErrorId : NullArray

対象となるウィンドウが取得できていない状態です。

$MAIN_WINDOW_TITLEのところの設定を見直してください。

また、操作対象のウィンドウが立ち上がっていることを確認してください。

ウィンドウの幅、高さが変わらない

$widthと$heightの値が小さすぎるか大きすぎる可能性があります。

$widthと$heightの設定を変更してみてください。

UI AutomationとPowerShellを組み合わせると結構自動化できる

今回はごくごく簡単にウィンドウを動かす、サイズを変えるというプログラムでしたが、UI AutomationとPowerShellを組み合わせることで、特別な環境を構築することなく、Windowsのユーザー操作を自動化することができます。

このブログでも関連する技術情報を発信していければと思っています。

終わりに

PowerShellとUI Automationを使った、ウィンドウを移動・サイズを変更する最も簡単なプログラムの紹介でした。

テレワークと出社等で違うディスプレイに頻繁に切替をしているとたまにウィンドウってどこか行ってしまいますよね。

そんなときにも便利かも??

また、ウィンドウの操作は、RPA的なことを自前でやりたい人にとってもとっかかりとしていい題材だと思います。

自動化の選択肢の一つとして、PowerShellとUI Automationはどうでしょうか。

ドキュメントがまだまだ少ないのがネックですが・・・。

このブログでも引き続きがんばって紹介していこうと思います。

というわけで、ここまでお読みいただき、ありがとうございました。

Windows APIによるウィンドウの移動もできるよ!

www.tekizai.net