using System; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using System.Windows; using Windows.Data.Xml.Dom; using Windows.UI.Notifications; using DesktopToastsSample.ShellHelpers; namespace DesktopToastsSample { public partial class MainWindow : Window { private const String APP_ID = "Microsoft.Samples.DesktopToasts"; public MainWindow() { InitializeComponent(); RegisterAppForNotificationSupport(); NotificationActivator.Initialize(); ShowToastButton.Click += ShowToastButton_Click; this.Closing += CloseMainWindow; } public void ToastActivated() { Dispatcher.Invoke(() => { Activate(); Output.Text = "The user activated the toast."; }); } private void CloseMainWindow(object sender, CancelEventArgs e) { NotificationActivator.Uninitialize(); } // In order to display toasts, a desktop application must have a shortcut on the Start menu. // Also, an AppUserModelID must be set on that shortcut. // // For the app to be activated from Action Center, it needs to register a COM server with the OS // and register the CLSID of that COM server on the shortcut. // // The shortcut should be created as part of the installer. The following code shows how to create // a shortcut and assign the AppUserModelID and ToastActivatorCLSID properties using Windows APIs. // // Included in this project is a wxs file that be used with the WiX toolkit // to make an installer that creates the necessary shortcut. One or the other should be used. // // This sample doesn't clean up the shortcut or COM registration. private void RegisterAppForNotificationSupport() { String shortcutPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Microsoft\\Windows\\Start Menu\\Programs\\Nitro Desktop Toasts Sample CS.lnk"; if (!File.Exists(shortcutPath)) { // Find the path to the current executable String exePath = Process.GetCurrentProcess().MainModule.FileName; InstallShortcut(shortcutPath, exePath); RegisterComServer(exePath); } } private void InstallShortcut(String shortcutPath, String exePath) { IShellLinkW newShortcut = (IShellLinkW)new CShellLink(); // Create a shortcut to the exe newShortcut.SetPath(exePath); // Open the shortcut property store, set the AppUserModelId property IPropertyStore newShortcutProperties = (IPropertyStore)newShortcut; PropVariantHelper varAppId = new PropVariantHelper(); varAppId.SetValue(APP_ID); newShortcutProperties.SetValue(PROPERTYKEY.AppUserModel_ID, varAppId.Propvariant); PropVariantHelper varToastId = new PropVariantHelper(); varToastId.VarType = VarEnum.VT_CLSID; varToastId.SetValue(typeof(NotificationActivator).GUID); newShortcutProperties.SetValue(PROPERTYKEY.AppUserModel_ToastActivatorCLSID, varToastId.Propvariant); // Commit the shortcut to disk ShellHelpers.IPersistFile newShortcutSave = (ShellHelpers.IPersistFile)newShortcut; newShortcutSave.Save(shortcutPath, true); } private void RegisterComServer(String exePath) { // We register the app process itself to start up when the notification is activated, but // other options like launching a background process instead that then decides to launch // the UI as needed. string regString = String.Format("SOFTWARE\\Classes\\CLSID\\{{{0}}}\\LocalServer32", typeof(NotificationActivator).GUID); var key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(regString); key.SetValue(null, exePath); } // Create and show the toast. // See the "Toasts" sample for more detail on what can be done with toasts private void ShowToastButton_Click(object sender, RoutedEventArgs e) { // Get a toast XML template XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastImageAndText04); // Fill in the text elements XmlNodeList stringElements = toastXml.GetElementsByTagName("text"); for (int i = 0; i < stringElements.Length; i++) { stringElements[i].AppendChild(toastXml.CreateTextNode("Line " + i)); } // Specify the absolute path to an image as a URI String imagePath = new System.Uri(Path.GetFullPath("toastImageAndText.png")).AbsoluteUri; XmlNodeList imageElements = toastXml.GetElementsByTagName("image"); imageElements[0].Attributes.GetNamedItem("src").NodeValue = imagePath; // Create the toast and attach event listeners ToastNotification toast = new ToastNotification(toastXml); toast.Activated += ToastActivated; toast.Dismissed += ToastDismissed; toast.Failed += ToastFailed; // Show the toast. Be sure to specify the AppUserModelId on your application's shortcut! ToastNotificationManager.CreateToastNotifier(APP_ID).Show(toast); } private void ToastActivated(ToastNotification sender, object e) { ToastActivated(); } private void ToastDismissed(ToastNotification sender, ToastDismissedEventArgs e) { String outputText = ""; switch (e.Reason) { case ToastDismissalReason.ApplicationHidden: outputText = "The app hid the toast using ToastNotifier.Hide"; break; case ToastDismissalReason.UserCanceled: outputText = "The user dismissed the toast"; break; case ToastDismissalReason.TimedOut: outputText = "The toast has timed out"; break; } Dispatcher.Invoke(() => { Output.Text = outputText; }); } private void ToastFailed(ToastNotification sender, ToastFailedEventArgs e) { Dispatcher.Invoke(() => { Output.Text = "The toast encountered an error."; }); } } }