65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2017年5月14日

MIT

2分钟阅读

viewsIcon

19642

downloadIcon

602

一种无需使用 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# 友好的代码。如果您不喜欢这种方法,还有另一种更简单、令人惊讶的、没有在任何地方提及的方法可以“唤醒”您的应用程序,当一个提示被激活时。

异步可插拔协议来救援

Windows 允许您通过使用称为 URL 协议的东西来启动您的应用程序。您已经知道一些,例如 http: 或 ftp:。如果您使用 Process.Start(http://www.google.com),该字符串的第一部分 (http😊 被识别为与某个特定应用程序关联的 URL 协议。已经预定义了几个协议,但您可以轻松添加您自己的协议并将其与您的应用程序关联,如此处所述:https://msdn.microsoft.com/en-us/library/aa767914(v=vs.85).aspx
 
它就像
 
private 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
    }
}

关注点

这就是您需要对提示激活做出反应的全部内容。查看提供的完整示例。该示例还包括在开始菜单中注册一个快捷方式,因为这对于将通知保存在操作中心是必需的——否则它们会消失。  

历史

这是第一个版本。

© . All rights reserved.