Microsoft.Toolkit.Uwp.Notifications 是当前最稳、最轻量、最贴近原生 Toast 行为的方案,3 行代码即可弹出通知,要求 .NET 6+ 项目使用 net6.0-windows10.0.17763.0 或更高 TFM,需正确配置 NuGet 版本与项目框架。

直接用 Microsoft.Toolkit.Uwp.Notifications 是当前最稳、最轻量、也最贴近原生 Toast 行为的方案——它绕过了 XML 手写和 COM 激活器配置,只要项目配置对,3 行代码就能弹出通知。别碰老式 ToastNotificationManager.GetTemplateContent + XML DOM 那套,除非你明确要支持 Windows 8 或必须用旧模板。
确认项目目标框架和 NuGet 版本是否匹配
这是最容易卡住的一步:不是代码写错,而是环境没搭对。
-
Microsoft.Toolkit.Uwp.Notifications7.0+ 要求 .NET 6+ 项目必须使用net6.0-windows10.0.17763.0或更高 TFM(比如net8.0-windows10.0.19041.0),不能只写net6.0 - WPF/WinForms 桌面应用若还在用
packages.config,必须右键项目 → “将 packages.config 迁移到 PackageReference”,否则引用不生效 - .NET Framework 4.7.2 项目也能用,但需手动添加对
Windows.winmd的引用(路径通常在C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.17763.0\Windows.winmd) - 运行时看不到通知?先检查系统设置:「设置 > 系统 > 通知和操作」里确保你的应用名称出现在列表中且开关打开
发送基础 Toast 通知的最小可行代码
不需要注册唤醒协议、不用配 AppUserModelID、不依赖 MSIX 打包——纯桌面 EXE 也能跑起来。
确保已添加命名空间:using Microsoft.Toolkit.Uwp.Notifications;
然后执行:
new ToastContentBuilder()
.AddText("订单已提交")
.AddText("预计 2 小时内发货")
.Show();
-
.AddText()最多调用两次:第一个是标题(加粗),第二个是正文;第三次调用会被忽略 - 不加任何参数时,默认显示 7 秒,静音,无图标,使用应用默认图标的占位符(若未设置 AppUserModelID,则显示 Visual Studio 图标)
- 如果
.Show()报红,大概率是 TFM 不对或 NuGet 包版本低于 7.0 —— 运行Install-Package Microsoft.Toolkit.Uwp.Notifications -Version 7.1.2显式指定版本
让通知可点击并带回参:必须传 argument,但不用立刻处理激活
用户点击通知后想跳转到某页面、打开某对话框,关键不在“怎么弹”,而在“弹的时候带什么线索”。
- 必须用
.AddArgument("key", "value")带至少一个键值对,例如:.AddArgument("page", "order-detail").AddArgument("id", "12345") - 仅加
.AddArgument不会自动触发任何逻辑;真正响应靠ToastNotificationManagerCompat.OnActivated事件,但它只在应用处于后台或未启动时才有意义 - 如果你的应用始终前台运行(如 WPF 主窗口常驻),点击通知默认只会唤起窗口,无需额外监听;只有需要区分“从通知进来的”和“从按钮点进来的”行为时,才需解析
toastArgs.Argument - 注意:未打包桌面应用若没设 AppUserModelID,
OnActivated事件可能收不到 —— 此时建议先用Application.Current.MainWindow.Activate()唤起窗口,再查Environment.GetCommandLineArgs()是否含通知参数(较迂回但可靠)
图片、按钮、输入框等高级元素的硬约束
不是所有功能在所有场景下都可用,尤其对未打包桌面应用。
- 本地图片必须用绝对路径,且协议头为
file:///(三个斜杠),例如:file:///C:/app/assets/icon.png;Web 地址、相对路径、pack://资源均无效 - 按钮和输入框(如
ToastSelectionBox)能渲染出来,但点击后触发的OnActivated事件,在未打包应用中无法获取toastArgs.UserInput(返回空字典),这是 Windows API 层限制,非代码问题 - 音频需用
.AddAudio(new Uri("ms-winsoundevent:Notification.Default")),自定义音频文件路径同样必须为绝对file:///形式,且格式限 WAV - 进度条(
.AddProgressBar())只支持“确定进度”模式,不支持无限循环动画;更新进度需重新发一条新通知并指定相同tag和group
真正难的不是“怎么弹出来”,而是“弹出来之后用户点了怎么办”——尤其是未打包应用在没有 COM 激活器或 AppUserModelID 的情况下,OnActivated 的行为差异极大,务必在 Windows 10/11 多版本实机验证,别只信模拟器或文档描述。











