@@ -10,6 +10,7 @@ use tauri::{
1010 AppHandle , Runtime ,
1111} ;
1212use windows:: core:: { Interface , HSTRING } ;
13+ use windows:: ApplicationModel :: Package ;
1314use windows:: Data :: Xml :: Dom :: XmlDocument ;
1415use windows:: Foundation :: { DateTime , TypedEventHandler } ;
1516#[ cfg( feature = "push-notifications" ) ]
@@ -21,6 +22,19 @@ use windows::UI::Notifications::{
2122 ToastNotificationManager , ToastNotifier ,
2223} ;
2324
25+ /// True when the current process has MSIX package identity.
26+ ///
27+ /// WinRT notification APIs split into two flavors: no-arg variants that use the
28+ /// package's default AUMID (only valid for packaged apps), and `*WithId`
29+ /// variants that take an explicit AUMID (only valid for unpackaged apps whose
30+ /// AUMID is registered via a Start Menu shortcut). Passing an arbitrary string
31+ /// to the WithId variants from inside an MSIX returns ERROR_NOT_FOUND because
32+ /// the real AUMID is `<PackageFamilyName>!<Application Id>` and the family-name
33+ /// hash is install-time only.
34+ fn is_packaged ( ) -> bool {
35+ Package :: Current ( ) . is_ok ( )
36+ }
37+
2438use crate :: error:: { ErrorResponse , PluginInvokeError } ;
2539use crate :: models:: * ;
2640
@@ -38,6 +52,7 @@ impl From<windows::core::Error> for crate::Error {
3852/// Shared plugin state wrapped in Arc for thread-safe access.
3953pub struct WindowsPlugin {
4054 app_id : String ,
55+ packaged : bool ,
4156 notifier : ToastNotifier ,
4257 action_types : RwLock < HashMap < String , ActionType > > ,
4358 click_listener_active : RwLock < bool > ,
@@ -49,6 +64,7 @@ impl std::fmt::Debug for WindowsPlugin {
4964 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
5065 f. debug_struct ( "WindowsPlugin" )
5166 . field ( "app_id" , & self . app_id )
67+ . field ( "packaged" , & self . packaged )
5268 . finish_non_exhaustive ( )
5369 }
5470}
@@ -134,10 +150,16 @@ pub fn init<R: Runtime, C: DeserializeOwned>(
134150 _api : PluginApi < R , C > ,
135151) -> crate :: Result < Notifications < R > > {
136152 let app_id = app. config ( ) . identifier . clone ( ) ;
137- let notifier = ToastNotificationManager :: CreateToastNotifierWithId ( & HSTRING :: from ( & app_id) ) ?;
153+ let packaged = is_packaged ( ) ;
154+ let notifier = if packaged {
155+ ToastNotificationManager :: CreateToastNotifier ( ) ?
156+ } else {
157+ ToastNotificationManager :: CreateToastNotifierWithId ( & HSTRING :: from ( & app_id) ) ?
158+ } ;
138159
139160 let plugin = Arc :: new ( WindowsPlugin {
140161 app_id,
162+ packaged,
141163 notifier,
142164 action_types : RwLock :: new ( HashMap :: new ( ) ) ,
143165 click_listener_active : RwLock :: new ( false ) ,
@@ -470,12 +492,14 @@ impl<R: Runtime> Notifications<R> {
470492 let history = ToastNotificationManager :: History ( ) ?;
471493 let app_id = & self . plugin . app_id ;
472494 for id in notifications {
495+ let tag = HSTRING :: from ( id. to_string ( ) ) ;
473496 // Use app-scoped removal with empty group (consistent with GetHistoryWithId usage)
474- if let Err ( e) = history. RemoveGroupedTagWithId (
475- & HSTRING :: from ( id. to_string ( ) ) ,
476- & HSTRING :: new ( ) ,
477- & HSTRING :: from ( app_id) ,
478- ) {
497+ let res = if self . plugin . packaged {
498+ history. RemoveGroupedTag ( & tag, & HSTRING :: new ( ) )
499+ } else {
500+ history. RemoveGroupedTagWithId ( & tag, & HSTRING :: new ( ) , & HSTRING :: from ( app_id) )
501+ } ;
502+ if let Err ( e) = res {
479503 log:: error!( "Failed to remove notification {id}: {e}" ) ;
480504 }
481505 }
@@ -484,8 +508,11 @@ impl<R: Runtime> Notifications<R> {
484508
485509 pub async fn active ( & self ) -> crate :: Result < Vec < ActiveNotification > > {
486510 let history = ToastNotificationManager :: History ( ) ?;
487- let app_id = & self . plugin . app_id ;
488- let notifications = history. GetHistoryWithId ( & HSTRING :: from ( app_id) ) ?;
511+ let notifications = if self . plugin . packaged {
512+ history. GetHistory ( ) ?
513+ } else {
514+ history. GetHistoryWithId ( & HSTRING :: from ( & self . plugin . app_id ) ) ?
515+ } ;
489516
490517 let mut result = Vec :: new ( ) ;
491518 for i in 0 ..notifications. Size ( ) ? {
@@ -533,8 +560,11 @@ impl<R: Runtime> Notifications<R> {
533560
534561 pub fn remove_all_active ( & self ) -> crate :: Result < ( ) > {
535562 let history = ToastNotificationManager :: History ( ) ?;
536- let app_id = & self . plugin . app_id ;
537- history. ClearWithId ( & HSTRING :: from ( app_id) ) ?;
563+ if self . plugin . packaged {
564+ history. Clear ( ) ?;
565+ } else {
566+ history. ClearWithId ( & HSTRING :: from ( & self . plugin . app_id ) ) ?;
567+ }
538568 Ok ( ( ) )
539569 }
540570
0 commit comments