マイナビニュースマイナビ

PowerShell 7 - ウィンドウのサイズを変えるスクリプト ver.0

【連載】

PowerShell Core入門 - 基本コマンドの使い方

【第157回】PowerShell 7 - ウィンドウのサイズを変えるスクリプト ver.0

[2021/07/16 08:00]後藤大地 ブックマーク ブックマーク

このところPowerShellにも関係があるWindows関連の新機能発表が続いたため、そちらを取り上げてきた。一通り説明は終えたので、PowerShellスクリプトの開発に話を戻そう。以前、スクリプトの体裁を成すために簡単な機能をベースにスクリプトを作成する方法について説明したが、今回はもっと実用的なスクリプトを作ってみよう。

ウインドウのサイズを変更する

書類の作成やマニュアルの作成を行っていると、アプリケーションのサイズが特定のサイズであってほしいことがある。サイズはケースバイケースだ。1200x1200かもしれないし、1000x600かもしれない。ウインドウサイズを変更するソフトウエアはいくつかあるので、そうしたものを使うのも一つの方法だ。

ウインドウのサイズ変更はWindowsの提供する基本的な機能の一つであり、実はPowerShellからも制御することができる。次はウインドウサイズを変更するPowerShellスクリプトを作成してみよう。このスクリプトはかなり実用的であり、容易に応用できるものになっている。

例えば作業をするにあたって、自分のお気に入りのアプリケーション配置があるとしよう。このアプリケーションはここにこのサイズで、このアプリケーションはここにこのサイズで……といった感じだ。通常、多くの方は手動でアプリケーションを起動し、マウスなどを操作して配置場所の移動とサイズの調整を行うだろう。しかし、PowerShellスクリプトを使えばこれを自動化できるのだ。

先人に学ぼう

同じようなことを考える人はいるもので、さらに作ったスクリプトをオープンソースで公開してくれていたりする。今回のケースだと、以下に掲載されているPowerShellスクリプトがとても良いサンプルだ。

win7 powershell script to automatically resize a minecraft window for 1280x720 HD fraps recording.


上記に掲載されているスクリプト「minecraft-sethd.ps1」の目的は、Windows 7で動作しているアプリケーション「Minecraft」のウインドウサイズを1280x720に変更するというものだ。

Windowsで実用的なスクリプトを開発するには、DLLファイルを読み込んで機能を取り込んで使う必要があり、上記のスクリプトでもuser32.dllからWindows APIを読み込んで使っている。user32.dllはウインドウ操作の基本的な機能を提供するDLLだ。

スクリプトそのものは短いので理解しやすいだろう。さらに、実はスクリプトの一部が開発者の意図とは違う動きをしていると思われる箇所があり、デバッグのサンプルとしても利用できる。短く、必要な機能が使われており、デバッグもでき、しかも成果物は実用的である。なかなか良いサンプルだ。

実際、スクリプト開発をしようというときにゼロから作るというケースは少ない。Webにはたくさんのサンプルコードやライブラリが存在しているし、ドキュメント類も充実している。材料を集め、そこからアイデアを得たり、実装方法を調べたりした上で開発してみる。このように何かしらのベースに基づいて開発していく学習スタイルのほうが、実際の開発には役立つと思う。

まずは動作を確認する

まずはサンプルのPowerShellを動かして動作を確認してみよう。動作させる前に、中身をちょっとだけ書き換える。ここでは、リサイズの対象をMinecraftではなく「設定アプリケーション」へ変更した。詳しい話は今後行っていくが、このスクリプトはウインドウタイトルの完全一致を絞り込みのルールとして使っている。「設定アプリケーション」は日本語環境では「設定」というウインドウタイトルだ。わかりやすいのでこのアプリケーションを対象とした。そしてスクリプト名も動作内容から「resize_1200x800_by_windowtitle.ps1」としてみた。

# Win7 Powershell script to resize windowtitle to 1200x800 (HD for fraps youtube capture)

# use by typing the following at a command prompt:
# > PowerShell -ExecutionPolicy Bypass -File resize_1200x800_by_windowtitle.ps1


# refs:
# http://stackoverflow.com/questions/2556872/how-to-set-foreground-window-from-powershell-event-subscriber-action
# http://richardspowershellblog.wordpress.com/2011/07/23/moving-windows/
# http://www.suite101.com/content/client-area-size-with-movewindow-a17846


Add-Type @"
  using System;
  using System.Runtime.InteropServices;

  public class Win32 {
    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
  }

  public struct RECT
  {
    public int Left;        // x position of upper-left corner
    public int Top;         // y position of upper-left corner
    public int Right;       // x position of lower-right corner
    public int Bottom;      // y position of lower-right corner
  }

"@


$rcWindow = New-Object RECT
$rcClient = New-Object RECT

$h = (Get-Process | where {$_.MainWindowTitle -eq "設定"}).MainWindowHandle

[Win32]::GetWindowRect($h,[ref]$rcWindow)
[Win32]::GetClientRect($h,[ref]$rcClient)

$width = 1200
$height = 800

$dx = ($rcWindow.Right - $rcWindow.Left) - $rcClient.Right
$dy = ($rcWindow.Bottom - $rcWindow.Top) - $rcClient.Bottom

[Win32]::MoveWindow($h, $rct.Left, $rct.Top, $width + $dx, $height + $dy, $true )

サイズもちょっと変えて、1200x800としてみた。書き換えたのは3行だ。変更部分は次のようになっている。

--- minecraft-sethd.ps1 2021-07-08 17:05:13.959207000 +0900
+++ resize_1200x800_by_windowtitle.ps1  2021-07-08 17:05:13.959350000 +0900
@@ -42,13 +42,13 @@
 $rcWindow = New-Object RECT
 $rcClient = New-Object RECT

-$h = (Get-Process | where {$_.MainWindowTitle -eq "minecraft"}).MainWindowHandle
+$h = (Get-Process | where {$_.MainWindowTitle -eq "設定"}).MainWindowHandle

 [Win32]::GetWindowRect($h,[ref]$rcWindow)
 [Win32]::GetClientRect($h,[ref]$rcClient)

-$width = 1280
-$height = 720
+$width = 1200
+$height = 800

 $dx = ($rcWindow.Right - $rcWindow.Left) - $rcClient.Right
 $dy = ($rcWindow.Bottom - $rcWindow.Top) - $rcClient.Bottom

上記ソースコードはいわゆるパッチと呼ばれるものだ。「unified diff」と呼ばれる形式のもので、これを見ればどこをどのように書き変えたのかわかるようになっている。詳しい説明は省くが、「@@」から始まる行がソースコードにおける該当行数、「-」から始まる行が削除された行、「+」から始まる行が追加された行、となっている。

resize_1200x800_by_windowtitle.ps1を実行してみよう。設定アプリケーションを起動した状態を用意する。

スクリプトの実行前

ここでスクリプトを実行すると、次のようになる。

スクリプトの実行後

サイズが1200x800へ変更されていることがおわかりいただけるだろうか。

本来であれば、左上の座標は変わらないまま、サイズだけが変わるように意図されたスクリプトだと思うのだが、この部分はコードが間違っていてスクリーンの左上へ移動してしまっている。しかし、結果的にどのように動作しているのか理解しやすくなっているのでサンプルとしては悪くない。

PowerShellからWindowsを制御する

C++やC#を使っているなら、Windowsを制御するプログラムを書くことはそれほど難しくない。これがPowerShellになると、Windowsの機能を呼び出す必要があることから、少しハードルが高くなる。しかし、スクリプトならばコンパイルする必要もなく、書いて実行すれば動くのだ。システムの機能を呼び出すのにこれほど楽なことはない。

実際にWindowsの制御がPowerShellから実行できることがわかってくると、PowerShellへの興味も湧くのではないだろうか。しばらくはこうした実用的なスクリプトの作り方などを説明していく。

※ 本記事は掲載時点の情報であり、最新のものとは異なる場合がございます。予めご了承ください。

一覧はこちら

連載目次

もっと知りたい!こちらもオススメ

【連載】RPA入門 - ツールで学ぶ活用シーン

【連載】RPA入門 - ツールで学ぶ活用シーン

AIには、ルールベース、機械学習、深層学習(ディープラーニング)の3つのレベルがあり、レベルが上がるに連れてより高度な人工知能を実現しますが、AIのスピンオフという位置付けで、Digital Labor(仮想知的労働者)によるホワイトカラー業務の自動化を実現するRPAが注目されています。

関連リンク

この記事に興味を持ったら"いいね!"を Click
Facebook で TECH+ の人気記事をお届けします
注目の特集/連載
[解説動画] Googleアナリティクス分析&活用講座 - Webサイト改善の正しい考え方
Slackで始める新しいオフィス様式
Google Workspaceをビジネスで活用する
ニューノーマル時代のオウンドメディア戦略
ミッションステートメント
次世代YouTubeクリエイターの成長戦略
IoTでできることを見つけるための発想トレーニング
教えてカナコさん! これならわかるAI入門
AWSではじめる機械学習 ~サービスを知り、実装を学ぶ~
Kubernetes入門
SAFeでつくる「DXに強い組織」~企業の課題を解決する13のアプローチ~
マイクロサービス時代に活きるフレームワーク Spring WebFlux入門
AWSで作るマイクロサービス
マイナビニュース スペシャルセミナー 講演レポート/当日講演資料 まとめ
セキュリティアワード特設ページ

一覧はこちら

今注目のIT用語の意味を事典でチェック!

一覧はこちら

会員登録(無料)

ページの先頭に戻る