PowerShellスクリプトでバルーンお知らせ

仕事でいろいろなことをスクリプトで自動化することがある。「これやらなきゃ」と思ってスクリプトを実行して、そのスクリプトがしばらくかかるものならメールをチェックしたり、他の作業を同時進行することが多いのだ。そんな状況でよくあるのが、そのスクリプトを実行したことさえも忘れてしまい、いろいろなウィンドウの後ろにコンソールウィンドウがひっそりと我慢強く待っていてくれたのを一時間ぐらい後に発見する。

こんなことが起きるのはスクリプトにはあまり目立ったお知らせ機能がないからだ。Outlookだと「ダディディン!」という音と共にポップアップウィンドウで会議があと何分後にあることを知らせてくれる。スクリプトだってそのプロセスが終わったことを知らせてくれるもっと目立つ機能があってもいいのではないかと考えてPowerShellでやってみた。次に紹介するのも.NET Frameworkのおかげなのだ。

まずはバルーン機能からやってみる。そもそもバルーンとは何か。下の画像を見ていただければ一目瞭然だ。

image

Windowsを使いなら一度は見たことがあるだろう。

まず最初に、矢印のアイコンに注目する。標準のアイコンというものはなく自分で指定してやらなければいけない。スクリプトが自分のコンピュータのみで動作するのだったらいいが、そのスクリプトが他のコンピュータにも配布されるということを想定して、アイコンをBase64の文字列に変換しスクリプト内に埋め込んでみる。まずはBase64文字列に変換する作業から。

まずはファイルをByte配列としてメモリに読み込む。それをBase64文字列に変換。ちなみに今回の記事でPowerShellらしいところといえばGet-Contentのみだろう。あとは.NET Frameworkを直接使っている。

image

このBase64文字列をスクリプト内に埋め込むことにする。

もう一度確認するが、このスクリプトの目的はバルーンを使ってスクリプトの実行が終了することをより視覚的に知らせることである。それをするために次のようなスクリプトを書いてみた。

#デフォルトではSystem.Windows.Formsは読み込まれていないので、それを初めに読み込む。
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
 
#NotifyIconクラスを使うので、インスタンスを作成。
$NotifyIcon = New-Object System.Windows.Forms.NotifyIcon
 
# アイコンを表すBase64文字列を変数に格納しておく。このようにしてアイコンやいろいろなバイナ
# リデータをBase64文字列としてスクリプト内に格納することも可能だが、データのサイズが大きい
# と文字列も長くなってしまうので注意。
$iconString = "AAABAAIAEBAAAAAAAABoAwAAJgAAABAQEAAAAAAAKAEAAI4DAAAoAAAAEAAAACAAA(HTMLの関係上略)"
 
# Base64文字列をByte配列に変換。
$binaryData = [System.Convert]::FromBase64String($iconString)
 
# 次の4行でByte配列に格納されていたアイコンをSystem.Drawing.Iconにして使えるようにする。
$memStream = New-Object System.IO.MemoryStream
$memStream.Write($binaryData, 0, $binaryData.Length)
$memStream.Position = 0
$icon = New-Object System.Drawing.Icon($memStream)
 
$memStream.Close()
 
# 最終的にIconプロパティを上で作ったIconオブジェクトにセットし、ShowballoonTipメソッドを
# 実行する。
$NotifyIcon.Icon = $icon
$NotifyIcon.Visible = $true
$NotifyIcon.ShowBalloonTip(100000, "俺のスクリプト", "スクリプトは終了しましたよ!", "Info")
 

これをファイルに格納してPowerShell上で実行すると、下のようにPowerShellからバルーンを使うことができる。

image

ちなみにSystem.Media.SoundPlayerを使えば音を鳴らすことだって可能だ。音を使えばより効果的であることは容易に想像できる。あまり詳しく説明しないが次のように音を鳴らすこともできるのだ。

$SoundPlayer = New-Object System.Media.SoundPlayer("$env:SystemRoot\Media\chimes.wav")
1..3 | foreach{$SoundPlayer.Play();[System.Threading.Thread]::Sleep(1000)}

コメント

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