このPowerShellスクリプトは、特定のファイルの変更を監視し、変更があったときに通知する目的で作られています。それでは、スクリプトの各部分について詳細に解説していきます。
1. 必要なアセンブリの追加
Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing
ここでは、GUI要素としてのフォームや通知アイコンを使用するために、System.Windows.Forms と System.Drawing のアセンブリを追加しています。
2. 監視するファイルのパス設定
$filePath = "C:\test.csv
この行で、監視対象のファイルパスを指定しています。
3. フォームと通知アイコンの作成
$form = New-Object System.Windows.Forms.Form $form.Text = "TEST" $form.Size = New-Object System.Drawing.Size(250,250) $notifyIcon = New-Object System.Windows.Forms.NotifyIcon $notifyIcon.Icon = [System.Drawing.Icon]::ExtractAssociatedIcon((Get-Command $MyInvocation.MyCommand.Definition).Source) $notifyIcon.Text = "ファイル監視中" $notifyIcon.Visible = $true
ここでは、アプリケーションのGUIとしてフォームを作成し、通知アイコンを設定しています。通知アイコンは、スクリプト自体のアイコンを使用しており、"ファイル監視中"というテキストが設定されています。
4. Runspaceでのファイル監視スクリプト
# Runspaceでのファイル監視スクリプト
$scriptBlock = {
param($filePath, $notifyIcon)
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = [System.IO.Path]::GetDirectoryName($filePath)
$watcher.Filter = [System.IO.Path]::GetFileName($filePath)
$watcher.NotifyFilter = [System.IO.NotifyFilters]::LastWrite
$watcher.IncludeSubdirectories = $false
# 変更が検出された際のアクション
$action = {
param($source, $event)
$changeType = $event.ChangeType
$fileName = $event.FullPath
$timeStamp = $event.TimeGenerated
# バルーン通知を表示
$notifyIcon.ShowBalloonTip(10000, "ファイル更新通知", "ファイルが更新されました: $fileName at $timeStamp ($changeType)", [System.Windows.Forms.ToolTipIcon]::Info)
}
Register-ObjectEvent -InputObject $watcher -EventName "Changed" -Action $action
$watcher.EnableRaisingEvents = $true
# イベントが発生するのを待つ
Wait-Event
}
このブロックでは、ファイル監視のためのメインロジックを定義しています。System.IO.FileSystemWatcher を使ってファイルの変更を監視し、変更があった場合に通知アイコンを使ってバルーン通知を表示します。
5. Runspaceの作成と実行
# Runspaceの作成と実行
$runspace = [runspacefactory]::CreateRunspace()
$runspace.ApartmentState = "STA"
$runspace.ThreadOptions = "ReuseThread"
$runspace.Open()
$runspace.SessionStateProxy.SetVariable("filePath", $filePath)
$runspace.SessionStateProxy.SetVariable("notifyIcon", $notifyIcon)
$powershell = [powershell]::Create().AddScript($scriptBlock).AddArgument($filePath).AddArgument($notifyIcon)
$powershell.Runspace = $runspace
$data = $powershell.BeginInvoke()
ここでは、非同期でファイル監視スクリプトを実行するためのRunspaceを作成し、スクリプトを実行しています。
6. フォームの表示とリソースのクリーンアップ
# フォームをモーダルダイアログとして表示 $form.ShowDialog() # リソースのクリーンアップ $notifyIcon.Dispose() $runspace.Close() $runspace.Dispose() $notifyIcon.Dispose() $powershell.EndInvoke($data) $powershell.Dispose()
最後に、フォームをモーダルダイアログとして表示し、終了時にはすべてのリソースを適切に解放しています。
このスクリプトは、PowerShellを用いたデスクトップアプリケーションの一例として非常に興味深いものです。GUI要素の利用、ファイル監視、非同期実行など、PowerShellの多面的な機能を活用しています。
全体コード
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# 監視するファイルのパス
$filePath = "C:\test.csv"
# フォームと通知アイコンの作成
$form = New-Object System.Windows.Forms.Form
$form.Text = "TEST"
$form.Size = New-Object System.Drawing.Size(250,250)
$notifyIcon = New-Object System.Windows.Forms.NotifyIcon
$notifyIcon.Icon = [System.Drawing.Icon]::ExtractAssociatedIcon((Get-Command $MyInvocation.MyCommand.Definition).Source)
$notifyIcon.Text = "ファイル監視中"
$notifyIcon.Visible = $true
# Runspaceでのファイル監視スクリプト
$scriptBlock = {
param($filePath, $notifyIcon)
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = [System.IO.Path]::GetDirectoryName($filePath)
$watcher.Filter = [System.IO.Path]::GetFileName($filePath)
$watcher.NotifyFilter = [System.IO.NotifyFilters]::LastWrite
$watcher.IncludeSubdirectories = $false
# 変更が検出された際のアクション
$action = {
param($source, $event)
$changeType = $event.ChangeType
$fileName = $event.FullPath
$timeStamp = $event.TimeGenerated
# バルーン通知を表示
$notifyIcon.ShowBalloonTip(10000, "ファイル更新通知", "ファイルが更新されました: $fileName at $timeStamp ($changeType)", [System.Windows.Forms.ToolTipIcon]::Info)
}
Register-ObjectEvent -InputObject $watcher -EventName "Changed" -Action $action
$watcher.EnableRaisingEvents = $true
# イベントが発生するのを待つ
Wait-Event
}
# Runspaceの作成と実行
$runspace = [runspacefactory]::CreateRunspace()
$runspace.ApartmentState = "STA"
$runspace.ThreadOptions = "ReuseThread"
$runspace.Open()
$runspace.SessionStateProxy.SetVariable("filePath", $filePath)
$runspace.SessionStateProxy.SetVariable("notifyIcon", $notifyIcon)
$powershell = [powershell]::Create().AddScript($scriptBlock).AddArgument($filePath).AddArgument($notifyIcon)
$powershell.Runspace = $runspace
$data = $powershell.BeginInvoke()
# フォームをモーダルダイアログとして表示
$form.ShowDialog()
# リソースのクリーンアップ
$notifyIcon.Dispose()
$runspace.Close()
$runspace.Dispose()
$notifyIcon.Dispose()
$powershell.EndInvoke($data)
$powershell.Dispose()