Windows 8でトースト通知を行ってみる
Windowsデスクトップアプリからのトースト通知
最近AWSに関する通知の事を考えることがあります。障害の通知といえば、メールによる通知、電話による通知などがよく用いられています。
そこで、ふとPCのデスクトップに障害通知を行ってみてはと思い、Windowsデスクトップ向けのトースト通知のサンプルアプリケーションを動かしてみました。
Windows 8でのトースト通知(デスクトップ通知)は下記のようなものになります:
デスクトップトースト通知サンプル
まず、下記からサンプルアプリケーションをダウンロードします。
C++版とC#版のサンプルがダウンロードできます。本記事ではC#版をダウンロードしています。
サンプルをダウロードしたら、プロジェクトフォルダを適当な場所に移動し、ToastNotificationSampleという名前にリネームしておきます。
Windows® API Code Pack for Microsoft® .NET Framework
このサンプルを実行するにはWindows® API Code Pack for Microsoft® .NET Frameworkが必要になります。
上記サイトからライブラリをダウンロードすることもできるのですが、NuGetでインストールすると楽ですので、今回はNuGetでインストールを行っておきます。
ダウンロードしたサンプルプロジェクトを開き、参照設定のNuGetパッケージの管理で下記をインストールしておきます:
- Windows 7 API Code Pack
- Windows 7 API Code Pack - Core
- Windows 7 API Code Pack - Shell
アプリケーションの画面構成
サンプルアプリケーションはWPFアプリケーションとなっています。まずは画面のコードを見て行きたいですが、画面のコードは非常に簡単なものとなっています。
画面のイメージは下記のようになります。
MainWindow.xamlのソースコードは下記のような非常にシンプルなものです。
<Window x:Class="DesktopToastsSample.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Desktop Toasts Sample" Height="200" Width="300"> <StackPanel Orientation="Vertical"> <Button x:Name="ShowToastButton" Height="50">Show Toast</Button> <TextBlock x:Name="Output" Margin="10" TextWrapping="Wrap">Whatever action you take on the displayed toast will appear here</TextBlock> </StackPanel> </Window>
スタートメニューショートカット作成処理
デスクトップアプリケーションがトーストを表示するためには、スタートメニューにショートカットを持っている必要があります。また、AppUserModelIDがそのショートカットに設定されている必要があります。この要件を実現するコードで、先ほど準備したWindows® API Code Pack for Microsoft® .NET Frameworkが必要になります。
スタートメニューショートカットの作成処理は下記のようになります:
private bool TryCreateShortcut() { String shortcutPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Microsoft\\Windows\\Start Menu\\Programs\\Desktop Toasts Sample CS.lnk"; if (!File.Exists(shortcutPath)) { InstallShortcut(shortcutPath); return true; } return false; } private void InstallShortcut(String shortcutPath) { String exePath = Process.GetCurrentProcess().MainModule.FileName; IShellLinkW newShortcut = (IShellLinkW)new CShellLink(); ShellHelpers.ErrorHelper.VerifySucceeded(newShortcut.SetPath(exePath)); ShellHelpers.ErrorHelper.VerifySucceeded(newShortcut.SetArguments("")); IPropertyStore newShortcutProperties = (IPropertyStore)newShortcut; using (PropVariant appId = new PropVariant(APP_ID)) { ShellHelpers.ErrorHelper.VerifySucceeded(newShortcutProperties.SetValue(SystemProperties.System.AppUserModel.ID, appId)); ShellHelpers.ErrorHelper.VerifySucceeded(newShortcutProperties.Commit()); } IPersistFile newShortcutSave = (IPersistFile)newShortcut; ShellHelpers.ErrorHelper.VerifySucceeded(newShortcutSave.Save(shortcutPath, true)); }
トースト通知処理
次に、トースト通知処理は下記のような処理の流れになります。
- トースト通知用のXMLを作成する
- 上記XMLを元にToastNotificationオブジェクトを作成する
- トーストの表示、消失時のイベントをToastNotificationオブジェクトに設定する
- ToastNotificationManagerを用いてトースト通知を実行する
実際の処理は下記のようになります:
private void ShowToastButton_Click(object sender, RoutedEventArgs e) { XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastImageAndText04);
XmlNodeList stringElements = toastXml.GetElementsByTagName("text"); for (int i = 0; i < stringElements.Length; i++) { stringElements[i].AppendChild(toastXml.CreateTextNode("Line " + i)); } String imagePath = "file:///" + Path.GetFullPath("toastImageAndText.png"); XmlNodeList imageElements = toastXml.GetElementsByTagName("image"); imageElements[0].Attributes.GetNamedItem("src").NodeValue = imagePath; ToastNotification toast = new ToastNotification(toastXml); toast.Activated += ToastActivated; toast.Dismissed += ToastDismissed; toast.Failed += ToastFailed; ToastNotificationManager.CreateToastNotifier(APP_ID).Show(toast); } [/csharp]
最後に
デスクトップアプリケーションからトースト通知ができるようになりました。これでサーバーで障害が発生した際に、デスクトップに通知を行ったり出来そうになりましたw
サンプルでは通知を起動させるアプリケーションが表示されていましたが、実際には画面が無い常駐アプリケーションからトースト通知を行いたいところです。これに関しては引き続き調査していきたいと思っています。