2014年7月21日月曜日

フォルダにファイルが作成されたこと をイベントトリガーにする

お久しぶりです。

転職&引っ越しをしてからやたら忙しい毎日を送っております。
今回は、別の勉強していたら面白い機能をネットで見かけたので備忘録がてら記事にしてみたり。
(決して本来の勉強の脱線じゃない!)


昔の現場で、以下の要件のPowerShellスクリプトを作成しました。
  • 特定のフォルダのファイル(XML)を読み込んで、とある処理をする。
  • そのファイル自体は、有ったり無かったりする。
    • つまり、ファイルが有れば処理実行。無ければ何もしない。


こんな感じ(↑)の実装をどうやったか。
  • タスクスケジューラでスクリプトを5分おきに実行し、フォルダ内をチェックする。
  • 特定のファイルが有れば処理実行。無ければ何もしない。


・・・はい。誰でも思いつく事ですね。無駄なリソース使ってますね。。。ゴメンナサイ。


そこで今回見つけた便利機能。
FileSystemWatcher クラス
ファイル システムの変更通知を待機し、ディレクトリまたはディレクトリ内のファイルが変更されたときにイベントを発生させます。

なんだよ。こんな便利機能あるんじゃないかよ。
一年前の自分に教えてあげたい・・・。


という訳で、拝借してきたスクリプトは以下。
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "C:\temp"
$watcher.Filter = "*.xml"
Register-ObjectEvent -InputObject $watcher -SourceIdentifier mywatch -EventName Created -Action {
 Write-Host "hoge"
}


実行結果。
Id     Name            PSJobTypeName   State         HasMoreData     Location 
--     ----            -------------   -----         -----------     -------- 
3      mywatch                         NotStarted    False                    


「C:\temp」内に.xmlファイルを置いてあげると、「hoge」ってコンソールに出てきます。


実際に使う時にはコンソールに文字出しても意味が無いので、-ActionのWrite-Host部分でイベントログにでもログを出して、そのログをトリガーにスクリプトを動かせば良い様な気がする。


確認するには
Get-EventSubscriber

SubscriptionId   : 3
SourceObject     : System.IO.FileSystemWatcher
EventName        : Created
SourceIdentifier : mywatch
Action           : System.Management.Automation.PSEventJob
HandlerDelegate  :
SupportEvent     : False
ForwardEvent     : False


削除するには
Unregister-Event -SourceIdentifier mywatch