前回、「getss.ps1」で取得するスクリーンショットのサイズを指定できるようにした。今回はこのスクリプトの構造を拡張していく。具体的には、Webブラウザで取得するスクリーンショットに加え、デスクトップやアプリケーションそのもののスクリーンショットを取得する機能を取り込むようにし、内部の構造を整える。

前回の成果物

前回は、Microsoft Edgeのヘッドレスモードでスクリーンショットを取得する際に、画像のサイズを指定できるようにPowerShellスクリプト「getss.ps1」を書き換えた。成果物は次の通りだ。

#!/usr/bin/env pwsh

#========================================================================
# スクリーンショットを取得する
#========================================================================

#========================================================================
# 引数を処理
#   -URL url        WebリソースのURL
#   -Width width    スクリーンショットの幅
#   -Height height  スクリーンショットの高さ
#========================================================================
Param(
    [Parameter(Mandatory=$true)][String]$URL = "",
    [Int]$Width = 1200,
    [Int]$Height = 800
)

#========================================================================
# デフォルトのスクリーンショットファイル
#========================================================================
$outfile="${env:HOME}/ss.png"

#========================================================================
# スクリーンショットの取得に利用するアプリケーション
#========================================================================
$msedge='C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe'

#========================================================================
# どの方法でスクリーンショットを取得するかを判断
#========================================================================
$method='msedge'

#========================================================================
# Webページのスクリーンショットを取得
#========================================================================
switch ($method)
{
    #================================================================
    # Microsoft Edgeを使って取得
    #================================================================
    'msedge'
    {
        $o1='--headless'
        $o2='--screenshot="' + ${outfile} + '"'
        $o3="--window-size=${Width},${Height}"

        Start-Process   -FilePath $msedge           `
                -ArgumentList $o1,$o2,$o3,$URL      `
                -Wait
        break
    }
}

getss.ps1には、Webページのスクリーンショットだけでなく、デスクトップやアプリケーションのスクリーンショットを取得する機能も持たせたいと思う。今回はこうした機能を取り込むための書き換えを行っていく。

まずは「Snipping Tool (SnippingTool.exe)」を使う

デスクトップやアプリケーションのスクリーンショットを取る機能は、PowerShellだけで実装することができる。Windowsがそうした機能を提供しているので、PowerShellからはそれらのAPIを呼び出して利用するコードを書けばよい。

ただし、その作業は結構な複雑なものになるので、今ここで取り上げるのはあまり適切ではないだろう。これに関しては、別の機会に説明したい。

今回は、Windowsがデフォルトで提供しているスクリーンショットを取得するアプリケーション「Snipping Tool (SnippingTool.exe)」を起動する処理を入れる、という程度の書き換えに留めておきたい。PowerShellを使った実装については、今後必要に応じて取り上げていく。

デスクトップのスクリーンショットも取れるようにする

前回までに作ったgetss.ps1は、引数としてURLを取るようになっている。Webページのスクリーンショットを取る目的で作ったのだから当然だ。しかし、ここにデスクトップのスクリーンショットを取る機能も追加したい。

ここでは引数をURLからURIへ拡張し、引数が「desktop:」、または何も指定されていなかった場合にデスクトップのスクリーンショットを取ることにする。そこで、まずは次のようにURIを引数として取るようにParam()を書き換える。

#========================================================================
# 引数を処理
#   -URI uri        スクリーンショットを取得するリソースのURI
#   -Width width    スクリーンショットの幅
#   -Height height  スクリーンショットの高さ
#========================================================================
Param(
    [Parameter(Mandatory=$false)][String]$URI = "desktop:",
    [Int]$Width = 1200,
    [Int]$Height = 800
)

Snipping Toolを起動するコマンドは「SnippingTool.exe」だ。詳細は割愛するが、執筆時点ではこのコマンドで該当するアプリケーションが起動するようになっている。将来的には実行されるコマンドが変わる可能性もあるので、とりあえず変数に格納しておく。

#========================================================================
# スクリーンショットの取得に利用するアプリケーション
#========================================================================
$msedge='C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe'
$snippingtool='SnippingTool.exe'

前回のgetss.ps1はMicrosoft Edgeのヘッドレスモードを使うことしか考えていなかったため、基本的に動作方法にはMicrosoft Edgeのみが選択される仕組みになっていた。今回この部分をURIによってMicrosoft EdgeかSnipping Toolかを切り分ける必要があるので、次のようにURIの内容に従って使用する方法を選択する処理へ書き換える。

#========================================================================
# どの方法でスクリーンショットを取得するか判断
#========================================================================
switch  -Wildcard ($URI)
{
    'http*'
    {
        #========================================================
        # Microsoft Edgeを使って取得
        #========================================================
        $method='msedge'
        break
    }

    'desktop:*'
    {
        #========================================================
        # Snipping Toolを使って取得
        #========================================================
        $method='snippingtool'
        break
    }
}

そして、スクリーンショットの取得方法としてSnipping Toolが選択されていた場合には、Snipping Toolを起動する処理も追加する必要がある。以下のような処理を追加することになる。

    #================================================================
    # Snipping Toolを使って取得
    #================================================================
    'snippingtool'
    {
        Start-Process   -FilePath $snippingtool 
        # ※ -Waitは定しても機能しない
        break
    }

これで主な書き換えは完了だ。getss.ps1が引数としてURLを前提としていた部分をURIへ変更し、URIとして独自に「desktop:」という指定を与えた。この部分は、将来的にはWindowsが使用しているほかのURIに対応させるなど、変更してもよい。暫定的な書き方だ。URIの指定で、特定のアプリケーションのスクリーンショットを取る機能を実装したりするのも面白いと思う。

今回のgetss.ps1

今回の書き換えをgetss.ps1へ反映すると次のようになる。

#!/usr/bin/env pwsh

#========================================================================
# スクリーンショットを取得する
#========================================================================

#========================================================================
# 引数を処理
#   -URI uri        スクリーンショットを取得するリソースのURI
#   -Width width    スクリーンショットの幅
#   -Height height  スクリーンショットの高さ
#========================================================================
Param(
    [Parameter(Mandatory=$false)][String]$URI = "desktop:",
    [Int]$Width = 1200,
    [Int]$Height = 800
)

#========================================================================
# デフォルトのスクリーンショットファイル
#========================================================================
$outfile="${env:HOME}/ss.png"

#========================================================================
# スクリーンショットの取得に利用するアプリケーション
#========================================================================
$msedge='C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe'
$snippingtool='SnippingTool.exe'

#========================================================================
# どの方法でスクリーンショットを取得するか判断
#========================================================================
switch  -Wildcard ($URI)
{
    'http*'
    {
        #========================================================
        # Microsoft Edgeを使って取得
        #========================================================
        $method='msedge'
        break
    }

    'desktop:*'
    {
        #========================================================
        # Snipping Toolを使って取得
        #========================================================
        $method='snippingtool'
        break
    }
}

#========================================================================
# スクリーンショットを取得
#========================================================================
switch ($method)
{
    #================================================================
    # Microsoft Edgeを使って取得
    #================================================================
    'msedge'
    {
        $o1='--headless'
        $o2='--screenshot="' + ${outfile} + '"'
        $o3="--window-size=${Width},${Height}"

        Start-Process   -FilePath $msedge           `
                -ArgumentList $o1,$o2,$o3,$URI      `
                -Wait
        break
    }

    #================================================================
    # Snipping Toolを使って取得
    #================================================================
    'snippingtool'
    {
        Start-Process   -FilePath $snippingtool 
        # ※ -Waitは指定しても機能しない
        break
    }
}

PowerShellスクリプトのメリットは、簡単に書き換えができる点にある。こうした書き換えを行う際は、いろいろ書いてみてシンプルでわかりやすいフローと構造にしていくのがお薦めだ。凝って難しい書き方をすると苦労するのは将来の自分なので、なるべく読んでスルッと理解できる内容になるように工夫しておく。

動作確認

作ったら動作確認だ。次のように引数なしでgetss.ps1を実行する。

getss.ps1

または、次のように引数に「desktop:」を指定してgetss.ps1を実行する。

getss.ps1 desktop:

実行すると、次のようにSnipping Toolが起動することを確認できる。

  • getss.ps1から起動されたSnipping Tool

    getss.ps1から起動されたSnipping Tool

もちろん、引数にURI (URL)を指定すれば、前回までと同じように指定したWebページのスクリーンショットを取得することができる。

この段階でデスクトップのスクリーンショットを取得する機能と統合したのは、全部作りきってから導入すると書き換えが多くて面倒だからだ。本来の開発の順序としては、Webページのスクリーンショットを取得するgetss.ps1を完成させてから、デスクトップのスクリーンショットを取得する機能を導入する流れになるのだが、そうすると書き換えがちょっと面倒になるので最初に導入させてもらった。こんな感じで、最初にある程度フローと構造を整理しておくと、後々の作業が楽になる。