在win10系統上彈出toast和notification


老規矩,先看效果

右下角的notification
這里寫圖片描述

操作中心的notification
這里寫圖片描述

整體效果
這里寫圖片描述

前提條件

1.需要在開始菜單里添加快捷方式。

2.在注冊表里注冊你實現了INotificationActivationCallBack接口的com組件。

3.一個APP_ID,添加到快捷方式里,ActionCenter會以此來區分不同應用的消息。

缺一不可,不然彈出的notification沒法交互。

實現

1.添加相關引用
編輯你項目的csproj文件,添加如下節點

<TargetPlatformVersion>10.0.10240.0</TargetPlatformVersion>

然后看起來就是這個樣子:
這里寫圖片描述

接下來打開引用管理器你會發現左邊多了一個Windows選項卡,然后添加圖示的三個引用:
這里寫圖片描述

然后再添加System.Runtime和System.Runtime.InteropServices.WindowsRuntime引用。
這里寫圖片描述
這兩個引用在:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5\Facades\文件夾中,如果你的.net 4.5.2的framework請改為v4.5.2。

2.添加快捷方式

private void InstallShortcut(String shortcutPath, String exePath)
        {
            IShellLinkW newShortcut = (IShellLinkW)new CShellLink();
            newShortcut.SetPath(exePath);
            newShortcut.SetWorkingDirectory(Path.GetDirectoryName(exePath));
            IPropertyStore newShortcutProperties = (IPropertyStore)newShortcut;
            PropVariantHelper varAppId = new PropVariantHelper();
            varAppId.SetValue(APP_ID);
            newShortcutProperties.SetValue(PROPERTYKEY.AppUserModel_ID, varAppId.Propvariant);
            PropVariantHelper varToastId = new PropVariantHelper();
            varToastId.VarType = VarEnum.VT_CLSID;
            varToastId.SetValue(typeof(NotificationActivator).GUID);
            newShortcutProperties.SetValue(PROPERTYKEY.AppUserModel_ToastActivatorCLSID, varToastId.Propvariant);
            ShellHelpers.IPersistFile newShortcutSave = (ShellHelpers.IPersistFile)newShortcut;
            newShortcutSave.Save(shortcutPath, true);
        }

3.注冊com組件

private void RegisterComServer(String exePath)
        {
            string regString = String.Format("SOFTWARE\\Classes\\CLSID\\{{{0}}}\\LocalServer32", typeof(NotificationActivator).GUID);
            var key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(regString);
            key.SetValue(null, exePath);
        }

這樣ActionCenter就可以通過GUID找到你的exe文件。
4.設置通知的內容樣式
通知的樣式有很多種,圖片、文字、按鈕、輸入框可以組合使用。詳情見最下面的參考鏈接。
這里我貼出下我例子里的布局設置。

private void btncl(object sender, RoutedEventArgs e)
        {
            ToastContent content = new ToastContent()
            {
                Visual = new ToastVisual()
                {
                    BindingGeneric = new ToastBindingGeneric()
                    {
                        Children =
                        {
                            new AdaptiveText()
                            {
                               Text="New Mirrored Folders Created"//標題
                            },
                           new AdaptiveText()
                           {
                               Text="Drag some files to either Mirror folder to sync\nClick to show the Mirror folder on my..."//內容
                           }
                        },
                        AppLogoOverride = new ToastGenericAppLogo()
                        {
                            Source = new System.Uri(System.IO.Path.GetFullPath("123.png")).AbsoluteUri//通知的圖標
                        }

                    }
                },
                Scenario = ToastScenario.Alarm,//設置通知的聲音

                //三個button
                Actions = new ToastActionsCustom()
                {
                    Buttons =
                    {
                        new ToastButton("PC",new QueryString(){
                            {"action","fileExplorer" },
                            {"path","c:\\" }
                        }.ToString())
                        {
                            ActivationType=ToastActivationType.Background
                        },
                        new ToastButton("Drive",new QueryString(){
                            {"action","fileExplorer" },
                            {"path","d:\\" }
                        }.ToString())
                        {
                            ActivationType=ToastActivationType.Background
                        },
                        new ToastButtonDismiss("Close")
                    }
                }
            };
            XmlDocument xml = new XmlDocument();
            xml.LoadXml(content.GetContent());
            ToastNotification toast = new ToastNotification(xml);
            toast.Group = "gg";
            //toast.ExpirationTime = DateTime.Now.AddSeconds(20);
            //toast.SuppressPopup = true;
            ToastNotificationManager.CreateToastNotifier(APP_ID).Show(toast);
        }

這里用到了兩個庫,分別是:
這里寫圖片描述
安裝完成后,添加引用即可。
1. 里面的QueryString.NET庫,是將key-value形式的集合,序列化成一個字符串,因為Notification里的button只接受一個為string類型的arguments。用戶點擊某個button時,會回調你com組件的Activie方法,在這個方法里拿到arguments,然后進行下一步操作。
2. 如果你不想讓右下角彈出通知,只想讓通知出現在“操作中心”(通知欄)里,可以設置toast.SuppressPopup=true來進行屏蔽。不過此時是沒法播放聲音的。
3. 關於如何讓通知常駐在”操作中心“這個問題,我發現是不可能的,微軟說了”當用戶與通知進行交互的時候會自動把這條通知從 操作中心移除“,所以那個toast.ExpirationTime基本沒啥作用。(詳見下面參考鏈接)。如果設置了Scenario = ToastScenario.Alarm(Reminder/IncomingCall);用戶不點擊的話,會一直出現在那里,否則7-8秒后自動消失。

5.程序退出時,清除通知
在退出時調用:

ToastNotificationManager.History.RemoveGroup(....);
//或者
ToastNotificationManager.History.Remove(....)

即可。這樣可以刪除同屬於一個Group的通知,或者刪除某個tag=”xxx”的通知,或者整個app_id下的通知。

6.如何做到多個win系統的兼容?
一般你的程序是同時支持win7,win8,win10等的,而win7是無法彈出這種樣式的通知的,所以這些引用不能直接添加到主程序里,不然運行時就會報錯。
正確的做法就是:將ToastNotification單獨做成一個dll,在程序中加入系統版本檢測的方法,如果是win10系統,再通過反射的方式,將dll加載到主程序集,然后再彈出通知。


附件:Demo。 如果失效,請留言或來信索取376720513@qq.com

如果你想更靈活的控制彈出的通知,可以參考我這篇博客:【WPF】右下角彈出自定義通知樣式(Notification)——簡單教程


2018-03-09更新:
NND,今天發現微軟更新了一篇又詳細的文章,介紹的很好,簡直手把手教你。
想看的請移步:Send a local toast notification from desktop C# apps

微軟官方介紹:https://docs.microsoft.com/zh-cn/windows/apps/design/shell/tiles-and-notifications/send-local-toast?tabs=uwp

 

《參考鏈接》

1.Quickstart: Handling toast activations from Win32 apps in Windows 10
2.github/desktop-toasts
3.Adaptive and interactive toast notifications
4.Send a local toast notification

 

出處:https://blog.csdn.net/catshitone/article/details/78522931

==========================================================================================

個人練習

我的開發環境是VS2017 ,使用framework4.6.1的環境,新建WinForm和wpf應用測試。

在項目的引用里,通過NuGet搜索並添加Microsoft.Toolkit.Uwp.Notifications的引用,我這里選擇的版本是7.1.2,添加完成后,編譯項目,會出現如下錯誤提示:

錯誤:  Must use PackageReference

解決方案:

需要在項目中的將packages.config遷移到PackageReference,具體操作如下:

Solution Explorer->右鍵單擊References->“將packages.config遷移到PackageReference”

 再次編譯,顯示編譯成功了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM