我们有一个桌面 Windows 应用程序(用 WFP/C# 编写),我们将其作为单个 .exe 文件分发,没有安装程序(它通过 Fody/Costura 插件捆绑了所有依赖项)。
我们想集成本地操作中心 toast 功能,应用程序可以在其中显示 toast 并在点击时响应它。
显示 toast 很简单,可以使用 Microsoft.Toolkit.Uwp.Notifications nuget 包来完成。但是,为了在操作中心(而不是气球提示)中单击 toast 时实际收到正确的通知,我们需要注册通知平台。
有关如何执行此操作的指南似乎侧重于带有安装程序(例如 Wix)的应用程序:https://learn.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/send-local-toast-desktop?fbclid=IwAR2AoHRKI88VNGRG-pTUytwhkMuovWT4bEr0RoXEayWpWsoGlghtZeq4Mo4#step-4-register-with-notification-platform
我们试图实现的具体任务是,来自文档:
If you're using classic Win32 (or if you support both), you have to declare your Application User Model ID (AUMID) and toast activator CLSID (the GUID from step #3) on your app's shortcut in Start.
不写安装程序怎么办?我们希望我们的应用在首次运行时进行注册。
注意:如果需要,该应用程序已经通过 UAC 提升自身,方法是在管理员上下文中重新启动自身。
其他引用资料:WPF native windows 10 toasts
[更新]
我设法按照 https://learn.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/send-local-toast-desktop 中的说明进行操作 和 https://learn.microsoft.com/en-us/windows/win32/shell/enable-desktop-toast-with-appusermodelid将本应有效的解决方案放在一起,但最后,单击操作中心中的 toast 不会触发我的 NotificationActivatior 中的 OnActivated()。
要点:
发送通知
var toast = new ToastNotification(toastXml); DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
注册:
string shortcutPath = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.Programs), "Toasty.lnk"); DesktopNotificationManagerCompat.RegisterAumidAndComServer <MyNotificationActivator>(AppName); DesktopNotificationManagerCompat.RegisterActivator <MyNotificationActivator>(); if (!File.Exists(shortcutPath)) { ShortcutManager.RegisterAppForNotifications( shortcutPath, Assembly.GetExecutingAssembly().Location, null, AppName, ActivationId); }
创建快捷方式
public static void RegisterAppForNotifications(
string shortcutPath,
string appExecutablePath,
string arguments,
string appName,
string activatorId)
{
var shellLinkClass = new ShellLinkCoClass();
IShellLinkW shellLink = (IShellLinkW)shellLinkClass;
shellLink.SetPath(appExecutablePath);
IPropertyStore propertyStore = (IPropertyStore)shellLinkClass;
IPersistFile persistFile = (IPersistFile)shellLinkClass;
if (arguments != null)
{
shellLink.SetArguments(arguments);
}
// https://learn.microsoft.com/en-us/windows/win32/properties/props-system-appusermodel-id
propertyStore.SetValue(
new PropertyKey("9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3", 5),
new PROPVARIANT(appName));
// https://learn.microsoft.com/en-us/windows/win32/properties/props-system-appusermodel-toastactivatorclsid
propertyStore.SetValue(
new PropertyKey("9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3", 26),
new PROPVARIANT(new Guid(activatorId)));
propertyStore.Commit();
persistFile.Save(shortcutPath, true);
}
[更新]
终于让它工作了 - 不确定之前出了什么问题,但最终版本似乎没问题。完整代码:https://gist.github.com/davidair/c4ea207bf6eece4ef08b97ab29a3036f
最佳答案
我现在的项目也遇到了同样的问题。
设法找到这个存储库 - https://github.com/felixrieseberg/electron-windows-interactive-notifications
这是安装快捷方式的 C++ 实现(InteractiveNotifications 文件,InstallShortcut 方法)。我想问题是我们如何将值设置为 PropertyStore,字符串 GUID 出于某种原因不适合。不过,我暂时无法解决问题。
更新:终于可以从代码安装快捷方式了!在 Github 上查看我的示例。 https://github.com/romayavorskyi/WpfNotificationTest (仍然有很多硬编码,但它应该给你一般的想法)。你是对的,捷径很重要。看来快捷方式应该在 ProgramData 文件夹中才能正常工作。
关于c# - 如何为本地 toast 通知自行注册独立桌面 C# WPF 应用程序(作为 exe 分发)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62490091/