PowerShellを活用したファイル監視と通知システムの構築

このPowerShellスクリプトは、特定のファイルの変更を監視し、変更があったときに通知する目的で作られています。それでは、スクリプトの各部分について詳細に解説していきます。

1. 必要なアセンブリの追加

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

ここでは、GUI要素としてのフォームや通知アイコンを使用するために、System.Windows.FormsSystem.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()

スポンサーリンク

-IT関連
-