PowerShell-GUIを使ったDrag&Drop

PowerShellスクリプトでファイル名などの引数を使用して起動する場合、エクスプローラー上でPS1ファイルに直接Drag&Dropを行うことはできない。
バッチファイルをかませるかリンクを作り、それらを経由した形になってしまう。

それだとちょっと面倒なので、PowerShellスクリプト内でGUIフォームを作成し、そこにファイルをDrag & Dropすることで引数としてのファイルを渡せるような仕組みにしたらどうかと思った。

一応検索したところ、海外では同様なことを考えている人が多くいて、次のサンプルを参考に作ってみた。

PowerShell Drag & Drop sample
PowerShell Drag & Drop sample. GitHub Gist: instantly share code, notes, and snippets.

今回利用したいのはファイル名で、それを内部のスクリプトに渡すことにしたいので、結果以下の様な実装になった。

# Drag & Dropでファイルを受け取る
Add-Type -AssemblyName System.Windows.Forms
function IsTargetFile ($filename) {
    if ([IO.Path]::GetExtension($filename) -eq ".png") {
        return $true
    }
    else {
        return $false
    }
}

$form = New-Object Windows.Forms.Form
$form.text = "Drag File"
$form.AllowDrop = $true
$form.Add_DragDrop({
    foreach ($filename in $_.Data.GetData([Windows.Forms.DataFormats]::FileDrop)) {
        if (IsTargetFile($filename)) {
            # $filename に対して処理をする実装を入れる
        }
    }
})
$form.Add_DragOver({
    foreach ($filename in $_.Data.GetData([Windows.Forms.DataFormats]::FileDrop)) {
        if (IsTargetFile($filename)) {
            $_.Effect = [Windows.Forms.DragDropEffects]::All
        }
    }
})
$form.ShowDialog()

IsTargetFileは処理対象の拡張子かどうかを調べる関数で、これが真の場合にドロップ可能としている。
今回PNGファイルを取り扱うことを考えていたので、拡張子が”.png”のものを真にしている。

Drop可能かどうかを判断しているのはDragOverのイベント処理で、可能なファイルの場合はEffectをAllにしている。
DragDropEffectsがとりうる値としてはいくつかあるのだけど、ここでは面倒なのでAllにしている。

DragOverで処理を行っていないと、DragDrop側に処理対象としてファイルが渡ってこなかったので注意が必要。
参考にしているGithub側はDragEnterイベントを使ってるけど、これはGUI内に入ったら発生するイベントだと思うので、ここではDragDropを使っている。

ファイルに対しての処理はDragDropないに入れるようにしていく。

コメント

タイトルとURLをコピーしました