Windowsトースト通知でリマインダ

# 目的

Windowsのトースト通知をリマインダとして使う。
<img width="317" alt="report.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425230/651a9d83-c02e-b670-21ad-28448f836e97.png">

もともと職場ではoutlookのスケジュールを定期業務のリマインダとして使っていましたが、次の理由からイマイチと感じており、PowerShell + タスクスケジューラ で実装するに至りました。

- 予定表として本来見たい会議予定等が埋もれてしまい見づらい（自分も他の人からも）
- リマインダ通知が出るとアクティブウィンドウが持っていかれてつらい

# 環境

- Windows 10 Pro
- PowerShell 5.1
- タスクスケジューラ

# 実装

root/
　├ toaster.ps1
　├ powershellLauncher.vbs
　└ xml/
　　└ sample.xml


- toaster.ps1
    - トースト通知を行うPowerShell本体。第一引数に通知内容を定義したxmlをとる。
- powershellLauncher.vbs
    - PowerShellをバックグラウンド実行する処理。タスクスケジューラから直接PowerShell.exeを呼ぶと青いコンソール画面が出てしまうので対策として。
- sample.xml
    - 通知内容の定義。

### PowerShell

```powershell:toaster.ps1
# Refer Windows Runtime
[Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] > $null
[Windows.UI.Notifications.ToastNotification, Windows.UI.Notifications, ContentType = WindowsRuntime] > $null

# Read toast template xml as [Windows.Data.Xml.Dom.XmlDocument] object
$template = Get-Content $Args[0]
$xml = New-Object Windows.Data.Xml.Dom.XmlDocument
$xml.LoadXml($template)

# Toast notify
$app = '{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.exe'
$toast = New-Object Windows.UI.Notifications.ToastNotification $xml
[Windows.UI.Notifications.ToastNotificationManager]:: CreateToastNotifier($app).Show($toast)
```

- $app
    - アプリケーションIDを指定する。通知がどのアプリケーションから発信されたものかを設定する。例ではPowerShell.exeを指定しているが任意のアプリケーションを指定可能。PowerShellコンソールでGet-StartAppsを実行した出力から選択すればOK。

### VBS

```vb:powershellLauncher.vbs
CreateObject("WScript.Shell").Run "powershell -ExecutionPolicy RemoteSigned -File " + WScript.Arguments(0) + " " + WScript.Arguments(1), 0
```

WScriptからPowerShell.exeを起動。VBSの第一引数には実行するPowerShell本体を、第二引数にはPowerShellに渡す引数（＝xmlファイル）を指定する。
Runの第二引数にゼロを指定することでPowerShellをバックグラウンド起動する。

### XML
```xml:sample.xml
<toast scenario="reminder">
    <visual>
        <binding template="ToastGeneric">
            <text>Toast was burnt</text>
            <image placement="appLogoOverride" src="C:\images\toaster.png"/>
        </binding>
    </visual>
    <actions>
        <input id="snoozeTime" type="selection" defaultInput="15">
            <selection id="1" content="1 minute"/>
            <selection id="15" content="15 minutes"/>
            <selection id="60" content="1 hour"/>
            <selection id="240" content="4 hours"/>
            <selection id="1440" content="1 day"/>
        </input>
        <action activationType="system" arguments="snooze" hint-inputId="snoozeTime" content="" />
        <action activationType="system" arguments="dismiss" content=""/>
     </actions>
     <audio silent="true"/>
</toast>
```

詳しくは[公式ドキュメント](#microsoft公式ドキュメント)参照。

- \<toast>
    - scenarioには下記を指定可能。

        |指定|挙動|
        |:---|:---|
        |属性無し|通知は数秒表示された後消える。|
        |reminder|通知は「再通知」「解除」を押すまで消えない。|
        |alarm|通知は「再通知」「解除」を押すまで消えない。アラーム音をループで流す。|
        |incomingCall|通知は「再通知」「解除」を押すまで消えない。Windows Mobileの場合全画面表示になる。それ以外はalarmと同様。|

- \<binding>
    - templateはToastGenericを指定。Web上ではToastText02が指定されている記事を見かけますが、Windows8までの古い形式。  
    https://docs.microsoft.com/en-us/previous-versions/windows/apps/hh761494(v=win.10)
    - imageタグで画像の表示も可能。  
<img width="294" alt="toast2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425230/a0c07369-3144-c879-940d-f0614caca7f9.png">

```xml
        <binding template="ToastGeneric">
            <text>Toast was burnt</text>
            <text>Don't forget to spread butter.</text>
            <image placement="appLogoOverride" hint-crop="circle" src="C:\images\たい焼き.jpg"/>
            <image placement="hero" src="C:\images\トースト.jpg"/>
            <image src="C:\images\クロワッサン.jpg"/>
        </binding>
```

- \<actions>
    - ドロップダウンリストに表示する再通知までの時間を設定可能。任意時間を指定できるが、選択肢は5つまで。

### タスクスケジューラ

<img width="334" alt="taskscheduler2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425230/6554a2b7-508e-b407-173c-4fbe850178b0.png">

# 関連リンク

#### Microsoft公式ドキュメント
https://docs.microsoft.com/ja-jp/windows/uwp/design/shell/tiles-and-notifications/toast-xml-schema
https://docs.microsoft.com/ja-jp/windows/uwp/design/shell/tiles-and-notifications/adaptive-interactive-toasts

#### ソース公開
https://github.com/onokit/toaster