This post was prompted by the discussion over the fact that Windows 8 boots into the Start screen, and cannot apparently be modified to boot into the Desktop (though no doubt someone will find a way).
What if, I wondered, you put a desktop app into your startup folder so it runs automatically on boot? The answer: it runs on the desktop, but you will not see it until you click or tap into the desktop from the start screen. This is different behaviour from actually starting a desktop app from the start screen, which switches you to the desktop.
So what if that desktop app has something important to tell you? The answer: you will not see it until you switch to the desktop.
To demonstrate this, I wrote a Windows Forms app that displays a MessageBox alert after a 5 second delay. I ran the app, activated the alert, and switched to a Windows Runtime
Metro app. When the alert fired, I heard a little ding, but saw no message. Only after switching to the desktop did I see the message.
To be fair, you might not see this even if you were working in the desktop, since Windows has complex (and sometimes unpredictable) rules about when apps are allowed to come to the foreground. Even calling the Activate method, which gives your window the focus, may do no more than flash the icon on the taskbar.
Windows 8 has a new-style “toast” notification mechanism that works across both desktop and Windows runtime. I got this working in my Windows Forms app.
So how do you do this? For some background, see Jim O’Neil’s series of posts which start here. However, I mostly used code from the sample Sending toast notifications from desktop apps. This is a WPF application, but I got the code to work in my Windows Forms application.
Note that to reference Windows.UI.Notifications you have to add a reference to:
C:\Program Files (x86)\Windows Kits\8.0\References\CommonConfiguration\Neutral\Windows.winmd
Update: in the release version of Visual Studio 2012 the way you reference winmd has changed. See this MSDN article and the section called Core Subgroup; however at the time of writing the method described there does not quite work. Instead, proceed as follows. First right-click the project in the Solution Explorer and choose Unload Project. Then right-click the project again and choose Edit [project].csproj. Add the following to the project file after the other Reference elements:
<Reference Include="Windows" />
then save and close the editor. Finally, right-click the project name again and choose Reload project. Do not add the suggested TargetPlatformVersion element, since if you do the project will not compile.
You also need the Windows 7 API code pack which is here.
Here is a quick summary though. In order to display a toast notification, you first need a shortcut to your app on the Start menu. In addition, the shortcut has to have an AppUserModeId, which you can set in code.
Once that is sorted, you can use the ToastNotificationManager class – for which you need that reference to Windows.UI.Notifications – and retrieve a standard XML template for the notification. You can add event handlers to the notification, so you can respond if the user clicks it. Then call:
to actually show the notification.
Note that your event handlers will not fire on the UI thread, so you need to use thread-safe methods if you want to interact with controls on your form.
It is all somewhat laborious, but on the plus side you get notifications which are better than the old notification area toast, and much better than MessageBox.
Note that this is one bit of code applications will only have if they are modified to work on Windows 8. That is worth noting if you have an application in which notifications play an important role.