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

PowerShell 7 - ウインドウのサイズを変えるスクリプト プラスアルファ

【連載】

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

【第163回】PowerShell 7 - ウインドウのサイズを変えるスクリプト プラスアルファ

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

ウインドウのサイズを変更するPowerShellスクリプトについては前回の説明で終わりにする予定だった。だが、前回までの説明だと少し応用しにくい部分があったので、補足として説明を追加しようと思う。

前回作成したPowerShellスクリプト「window_resizer.ps1」では、次の3つをキーとしてウインドウサイズを変更する対象を絞り込んでいる。

  1. プロセス名
  2. MainWindowHandleプロパティの値が0以外(つまり、ウインドウを持っている)
  3. ウインドウタイトル


PowerShellでは、プロセスのデータは次のようにGet-Processコマンドレットで取得する。

Get-Process

Get-Processコマンドレットの実行サンプル

この状態だと、取得できる全てのプロセスの情報が表示される。ウインドウを持たないプロセスも含まれているため、window_resizer.ps1で使うには扱いにくい。前提条件として「ウインドウを持たないプロセス」は扱うことがないのだから、ウインドウを持っているプロセスの情報だけを確認し、対象となるプロセスを知りたい。その場合、次のようにコマンドレットを実行すればよい。

Get-Process | ? {$_.MainWindowHandle -ne 0}

Get-Processコマンドレットの出力を、ウインドウを持ったものへ絞り込む

プロセスのMainWindowHandleの値が「0」のものはウインドウを持たないので、これで切り分けを行っている。

そして、知りたいのはプロセス名とウインドウタイトルなのだから、その情報だけがわかればよい。そこで、先ほどの結果を次のようにFormat-Tableコマンドレットへ流し込んで出力する。

Get-Process | ? {$_.MainWindowHandle -ne 0} | Format-Table -Property Id,ProcessName,MainWindowTitle

Format-Tableで欲しい出力だけを表形式で出力

Format-Tableコマンドレットは「-Property」で表示するプロパティを指定することができる。ここに「Id,ProcessName,MainWindowTitle」を指定しておけば、プロセス番号、プロセス名、ウインドウタイトルだけが表示されるようになる。

とは言え、毎回window_resizer.ps1で指定するプロセスを調べるのは面倒だ。そこで、このプロセス情報を表示する機能をwindow_resizer.ps1へ取り込んでいこう。

機能をwindow_resizer.ps1へマージする

ここでは、window_resizer.ps1に「-WindowProcessList」というパラメータを追加してみよう。このパラメータは、引数を取らずに単体で使用するものとする。window_resizer.ps1のパラメータリストに、次のように「WindowProcessList」というパラメータを追加する。

#====================================================================
# 引数を処理
#====================================================================
Param(
    [String]$ProcessName="*",   # プロセス名
    [String]$WindowTitle=".*",  # ウインドウタイトル(正規表現)
    [Int32]$Width="800",        # ウインドウ幅
    [Int32]$Height="600",       # ウインドウ高さ
    [Switch]$WindowProcessList  # ウインドウプロセス一覧を表示
)

そして、このパラメータが指定されていた場合に、先ほど実行したGet-Processの処理が行われるように次のコードを追加する。

#====================================================================
# ウインドウプロセスを一覧表示
#====================================================================
if ($WindowProcessList) {
    Get-Process                         | 
    ? {$_.MainWindowHandle -ne 0 }              | 
    Format-Table -Property Id,ProcessName,MainWindowTitle
    exit
}

短いコードであり、ちょっとした機能の追加でしかないのだが、これが結構便利なのだ。別スクリプトとして用意してもよいかもしれないが、使うのはwindow_resizer.ps1を実行するときなので、ここにまとめておくのがよいかと思う。ということで、window_resizer.ps1の最終版は次のようになる。

#!/usr/bin/env pwsh

#====================================================================
# 引数を処理
#====================================================================
Param(
    [String]$ProcessName="*",   # プロセス名
    [String]$WindowTitle=".*",  # ウインドウタイトル(正規表現)
    [Int32]$Width="800",        # ウインドウ幅
    [Int32]$Height="600",       # ウインドウ高さ
    [Switch]$WindowProcessList  # ウインドウプロセス一覧を表示
)

#====================================================================
# ウインドウプロセスを一覧表示
#====================================================================
if ($WindowProcessList) {
    Get-Process                         | 
    ? {$_.MainWindowHandle -ne 0 }              | 
    Format-Table -Property Id,ProcessName,MainWindowTitle
    exit
}

#====================================================================
# ウインドウサイズを変更する関数 Resize-Window
#====================================================================
Add-Type @"
using System;
using System.Runtime.InteropServices;

public struct RECT
{
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
}

public class WinAPI
{
    // ウインドウの現在の座標データを取得する関数
    [DllImport("user32.dll")]
    public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

    // ウインドウの座標を変更する関数
    [DllImport("user32.dll")]
    public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); 
}
"@

function Resize-Window {
    param (
        $wh  # ウインドウハンドラ
    )

    # ウインドウ座標データ構造体
    $rc = New-Object RECT

    # ウインドウの現在の座標データを取得
    [WinAPI]::GetWindowRect($wh, [ref]$rc) > $null

    # 左上の場所はそのままに、ウインドウのサイズを変更
    [WinAPI]::MoveWindow($wh, $rc.Left, $rc.Top, $width, $height, $true) > $null
}

#====================================================================
# 対象となるウインドウを選択し、サイズを変更
#====================================================================
Get-Process -Name $processName |
    ? { $_.MainWindowHandle -ne 0 } |
    ? { $_.MainWindowTitle -match "$windowTitle" } |
    % {
        # ウインドウサイズを変更
        Resize-Window($_.MainWindowHandle);
}

実行結果は次の通りだ。

window_resizer.ps1 -WindowProcessList

window_resizer.ps1 -WindowProcessListの実行結果

Windowsではアプリケーション名とプロセス名が必ずしも直感的に一致しておらず、どのプロセスが目的のウインドウなのか絞り込むのが難しいことがある。ちょっとした機能でしかないのだが、こうした機能を用意しておくと実務上、とても効果的なのだ。

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

一覧はこちら

連載目次

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

【連載】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用語の意味を事典でチェック!

一覧はこちら

会員登録(無料)

ページの先頭に戻る