Windows 消息推送通知(无需 COM 服务器)





5.00/5 (2投票s)
一种无需使用 COM 服务器即可响应 Windows 消息推送激活的简单方法
引言
从 Windows 8.0 开始,Microsoft 增加了提示通知的概念。与旧的 balloon 通知相比,提示通知可以在它们从屏幕上消失后保留在操作中心。这允许您的应用程序将通知保留更长的时间 (最多 3 天),并让您的用户稍后对其做出反应。
背景
正如 Microsoft 的这篇快速指南 (https://blogs.msdn.microsoft.com/tiles_and_toasts/2015/10/16/quickstart-handling-toast-activations-from-win32-apps-in-windows-10/) 所述,如果您希望在您的应用程序不再运行时对提示激活做出反应,则需要一个 COM 服务器来激活您的应用程序。这样做,您需要编写不太 C# 友好的代码。如果您不喜欢这种方法,还有另一种更简单、令人惊讶的、没有在任何地方提及的方法可以“唤醒”您的应用程序,当一个提示被激活时。
异步可插拔协议来救援
Process.Start
(http://www.google.com),该字符串的第一部分 (http😊 被识别为与某个特定应用程序关联的 URL 协议。已经预定义了几个协议,但您可以轻松添加您自己的协议并将其与您的应用程序关联,如此处所述:https://msdn.microsoft.com/en-us/library/aa767914(v=vs.85).aspxprivate void RegisterProtocol(string exePath)
{
// to register this url protocol for all users use LocalMachine instead and elevation of admin rights will be required
RegistryKey key = Registry.CurrentUser.OpenSubKey("Software\\Clases\\" + urlProtocol);//open myApp protocol's subkey
if (key == null) //if the protocol is not registered yet...we register it
{
key = Registry.CurrentUser.CreateSubKey("Software\\Classes\\" + urlProtocol);
key.SetValue(string.Empty, "URL: " + urlProtocol);
key.SetValue("URL Protocol", string.Empty);
key = key.CreateSubKey(@"shell\open\command");
key.SetValue(string.Empty, exePath + " " + "%1");
//%1 represents the argument - this tells windows to open this program with an argument / parameter
}
key.Close();
}
这对我们来说有什么有趣的?
如果您查看用于定义提示通知的 XML,您会注意到一个名为“activationType”的参数,并且值“protocol”对我们特别有趣。如果您使用此值,则需要指定用于启动此 URL 协议的字符串。为此,我们使用属性“launch”(或者在“arguments”中,如果您在操作中使用它)。
<toast launch="my-cool-app:arguments_for_my_app" activationType="protocol">
<visual>
<binding template="ToastGeneric">
<text>My test app using protocol</text>
</binding>
</visual>
</toast>
使用代码
上面的提示定义将导致,每当用户单击通知时,Windows 将尝试使用您为提示提供的参数来启动您的应用程序(这与 COM 激活方法不同,在这种方法中,我们让 Windows 知道我们的应用程序正在运行)。但是,我们不想在我们的应用程序已经运行时再次启动它,因为我们有对提示操作做出反应的事件。
// Create the toast and attach event listeners
ToastNotification toast = new ToastNotification(dom);
toast.Activated += Toast_Activated;
// Show the toast. Be sure to specify the AppUserModelId on your application's shortcut!
ToastNotificationManager.CreateToastNotifier(myAppID).Show(toast);
为确保提示不会再次启动我们的应用程序,我们需要实现一个互斥体以仅保持一个我们的应用程序实例运行。如果 Windows 尝试启动我们应用程序的新实例,我们将在初始化任何内容之前简单地将其关闭并忽略它。
public MainWindow()
{
bool createdNew;
// we want to prevent starting a new instance of the application through url protocol launch when our toast is activated and our application is already running
_mutex = new Mutex(true, AppName, out createdNew);
if (!createdNew)
{
//app is already running! Exiting the application
Application.Current.Shutdown();
}
else
{
InitializeComponent();
// other stuff
}
}
关注点
这就是您需要对提示激活做出反应的全部内容。查看提供的完整示例。该示例还包括在开始菜单中注册一个快捷方式,因为这对于将通知保存在操作中心是必需的——否则它们会消失。
历史
这是第一个版本。