その他

任意のフォルダのスクリーンショットを取得しクリップボードの画像をPNGで保存する(VBA、Powershell)[No94]

スポンサーリンク

任意のフォルダ(ダウンロードフォルダやデスクトップフォルダなど)を画像にして特定フォルダに保存するプログラムを用意しました。今回はそのプログラムを紹介します。

プログラムファイル

処理内容

このプログラムでは、次の構成で実行する必要があります。それぞれを起動すると起こることも併せて記載します。

 ・Excelマクロ:フォルダをアクティブにして、スクリーンショットを取得する(=画像はclipboardに保存されます)。

  なお、フォルダをアクティブにする際、フォルダが起動していない場合は起動しアクティブ、フォルダが起動している場合は何もせずアクティブにする。

 ・ps1ファイル:clipboardに保存された画像をファイルにして保存する。

実行は「Excelマクロ」、「ps1ファイル」の順で行っていきます。

構成

Excelマクロとして、デスクトップに「任意フォルダのスクリーンショットを取得.xlsm」を配置する。


'Declare PtrSafe Sub Sleep Lib "kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long)
Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

'Declare PtrSafe Sub keybd_event Lib "user32" Alias "keybd_event" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As LongPtr)
Declare PtrSafe Sub keybd_event Lib "user32" ( _
    ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As LongPtr)

'Declare PtrSafe Function BringWindowToTop Lib "user32" Alias "BringWindowToTop" (ByVal hwnd As LongPtr) As Long
Declare PtrSafe Function BringWindowToTop Lib "user32" (ByVal hwnd As LongPtr) As Long

Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" ( _
    ByVal lpClassName As String, _
    ByVal lpWindowName As String) As LongPtr
    
Public Sub Main()
    
    'フォルダパスを設定する※環境変数の名前を含む文字列を利用
    'ユーザープロファイル:Environ("USERPROFILE")
    Dim folderPath As String
    folderPath = Environ("USERPROFILE") & "\Downloads"
    
    Dim targetAppTitle As String
    targetAppTitle = "ダウンロード"
    
    Dim psFilePath As String
    psFilePath = "D:\Application\DNo00002\OutoutClipboard.ps1"
    
    Dim appFilePath As String
    appFilePath = "C:\Windows\Explorer.exe"
    
    If Dir(folderPath, vbDirectory) <> "" Then
    
        Dim hwnd As Long
        hwnd = FindWindow(vbNullString, targetAppTitle)
        
        If hwnd = 0 Then
            Shell appFilePath & " " & folderPath, vbNormalFocus
        Else
            BringWindowToTop hwnd
        End If
        
        timeWait ("00:00:03")
        
        'アクティブ画面スクリーンショット(Alt + PrintScreen)
        keybd_event &HA4, 0&, &H1, 0&
        keybd_event vbKeySnapshot, 0&, &H1, 0&
        keybd_event vbKeySnapshot, 0&, &H1 Or &H2, 0&
        keybd_event &HA4, 0&, &H1 Or &H2, 0&
        
        '全画面スクリーンショット
        'keybd_event vbKeySnapshot, 0&, &H1, 0&
        'keybd_event vbKeySnapshot, 0&, &H1 Or &H2, 0&
        
        timeWait ("00:00:03")
        
        Dim objWsh
        Set objWsh = CreateObject("WScript.Shell")
        
        Dim execCommand As String
        execCommand = "powershell -NoProfile -NoLogo -ExecutionPolicy Unrestricted " & psFilePath
        
        Dim result As Long
        result = objWsh.Run(Command:=execCommand, WindowStyle:=0, WaitOnReturn:=True)
        
        If (result = 0) Then
            Debug.Print ("Windows PowerShell 正常終了")
        Else
            Debug.Print ("Windows PowerShell 異常終了")
        End If

    Else
        Debug.Print folderPath & "が存在しません。ご確認ください。"
        GoTo ReleaseObject
    End If
    
ReleaseObject:
    Set objWsh = Nothing
End Sub

Public Sub timeWait(ByVal myTime As String)
    Dim waitTime As Date
    waitTime = Now + TimeValue(myTime)

    DoEvents
        Application.Wait waitTime
    DoEvents
End Sub

ps1ファイルとして、「D:\Application\DNo00002」に「OutoutClipboard.ps1」を用意する。

また、同階層の「D:\Application\DNo00002」に「output」フォルダを用意する。


#$wsobj = new-object -comobject wscript.shell
#$result = $wsobj.popup("Hello World")

#アセンブリ読み込み
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName System.Windows.Forms

$outputFolderPath01 = "D:\Application\DNo00002\output"
$nowDate = (Get-Date).ToString("yyyyMMdd_HHmm") 
$identificationName = "test"
$outputFolderPath02 = $nowDate + "_" + $identificationName

$outputFolderPath = ($outputFolderPath01 + "\" + $outputFolderPath02)

New-Item ($outputFolderPath) -ItemType Directory -Force

#各種設定
#■□■□
#何ミリ秒ごとに取得するか
$sleepTime = 250
#■□■□

#ミリ秒数停止
Start-Sleep -Milliseconds $sleepTime

#日時取得、座標編集
$nowTime = (Get-Date)
$nowTimeFileName = $nowTime.ToString("yyyyMMdd_HHmmss") 

#ファイル名編集
$outputFileName  = ($identificationName + "_" + $nowTimeFileName + ".png")

#クリップボードに画像があれば保存
$clipboardImage = [Windows.Forms.Clipboard]::GetImage()
if ($clipboardImage -ne $null)
{
	$outputFilePath =($outputFolderPath + "\" + $outputFileName)
	$clipboardImage.Save($outputFilePath)
}

実行イメージ

1.Excelマクロの「Main」関数を実行し、スクリーンショットを取得する。

  ※本記事のプログラムの場合は、最終的に以下の画像を取得する。

2.Excelマクロの処理で「ps1ファイル」を実行する。

  ※本記事のプログラムの場合は、「ps1ファイル」が実行すると「output」フォルダ内にフォルダが作成され、その内に画像ファイルが保存される。

補足

「OutoutClipboard.ps1」を直接起動(ファイルを右クリックし「PowerShellで実行」で実行)することが可能です。

もしも、上手くできないと思われた時は、どのプログラムは上手く動作している、や、どのプログラムのところで上手く行っていない等を調査してみましょう。

この処理結果をメール通知で知らせることも可能です。

備考

powershellのプログラムについては、似たようなことを以下リンク先の記事で紹介しています。

no image
簡単!PowerShellで作成できる画面録画ツールの紹介と作り方[No18]
前回、フリーソフト「ScreenToGif」と「UiPath」を用いてRPAプログラムの動作を確認する方法を紹介しましたが、フリーソフトの利用を嫌がる方もいると思います。 私もその一 ...

参考サイト

Microsoft.VisualBasic 名前空間

Interaction クラス

Interaction.Shell(String, AppWinStyle, Boolean, Int32) メソッド

AppWinStyle 列挙型


Microsoft.VisualBasic 名前空間

Environ(String)


アプリのスクリーンショットをpngファイルにする - Qiita

最後までお付き合いいただきありがとうございます!

この情報が誰かの役にたてれば幸いです。

スポンサーリンク

-その他