diff --git a/DesktopNotifications.FreeDesktop/FreeDesktopApplicationContext.cs b/DesktopNotifications.FreeDesktop/FreeDesktopApplicationContext.cs new file mode 100644 index 0000000..baa868c --- /dev/null +++ b/DesktopNotifications.FreeDesktop/FreeDesktopApplicationContext.cs @@ -0,0 +1,28 @@ +using System.Diagnostics; +using System.IO; + +namespace DesktopNotifications.FreeDesktop +{ + /// + /// + public class FreeDesktopApplicationContext : ApplicationContext + { + private FreeDesktopApplicationContext(string name, string? appIcon) : base(name) + { + AppIcon = appIcon; + } + + /// + /// + public string? AppIcon { get; } + + public static FreeDesktopApplicationContext FromCurrentProcess(string? appIcon = null) + { + var mainModule = Process.GetCurrentProcess().MainModule; + return new FreeDesktopApplicationContext( + Path.GetFileNameWithoutExtension(mainModule.FileName), + appIcon + ); + } + } +} \ No newline at end of file diff --git a/DesktopNotifications.FreeDesktop/FreeDesktopNotificationManager.cs b/DesktopNotifications.FreeDesktop/FreeDesktopNotificationManager.cs index 297c8e9..6f1b860 100644 --- a/DesktopNotifications.FreeDesktop/FreeDesktopNotificationManager.cs +++ b/DesktopNotifications.FreeDesktop/FreeDesktopNotificationManager.cs @@ -9,6 +9,7 @@ namespace DesktopNotifications.FreeDesktop { public class FreeDesktopNotificationManager : INotificationManager, IDisposable { + private readonly FreeDesktopApplicationContext _appContext; private const string NotificationsService = "org.freedesktop.Notifications"; private static readonly ObjectPath NotificationsPath = new ObjectPath("/org/freedesktop/Notifications"); @@ -19,8 +20,13 @@ namespace DesktopNotifications.FreeDesktop private IFreeDesktopNotificationsProxy? _proxy; - public FreeDesktopNotificationManager() + /// + /// + /// + /// + public FreeDesktopNotificationManager(FreeDesktopApplicationContext? appContext = null) { + _appContext = appContext ?? FreeDesktopApplicationContext.FromCurrentProcess(); _activeNotifications = new Dictionary(); } @@ -65,9 +71,9 @@ namespace DesktopNotifications.FreeDesktop var actions = GenerateActions(notification); var id = await _proxy.NotifyAsync( - "MyApp", + _appContext.Name, 0, - string.Empty, + _appContext.AppIcon ?? string.Empty, notification.Title ?? throw new ArgumentException(), notification.Body ?? throw new ArgumentException(), actions.ToArray(), diff --git a/Example/ShellLink.cs b/DesktopNotifications.Windows/ShellLink.cs similarity index 99% rename from Example/ShellLink.cs rename to DesktopNotifications.Windows/ShellLink.cs index 8ec1289..4cf6b7a 100644 --- a/Example/ShellLink.cs +++ b/DesktopNotifications.Windows/ShellLink.cs @@ -1,11 +1,10 @@ using System; -using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Text; -namespace Example.Win32 +namespace DesktopNotifications.Windows { // Modified from http://smdn.jp/programming/tips/createlnk/ // Originally from http://www.vbaccelerator.com/home/NET/Code/Libraries/Shell_Projects diff --git a/DesktopNotifications.Windows/WindowsApplicationContext.cs b/DesktopNotifications.Windows/WindowsApplicationContext.cs new file mode 100644 index 0000000..01e37e6 --- /dev/null +++ b/DesktopNotifications.Windows/WindowsApplicationContext.cs @@ -0,0 +1,47 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; + +namespace DesktopNotifications.Windows +{ + public class WindowsApplicationContext : ApplicationContext + { + private WindowsApplicationContext(string name, string appUserModelId) : base(name) + { + AppUserModelId = appUserModelId; + } + + public string AppUserModelId { get; } + + [DllImport("shell32.dll", SetLastError = true)] + private static extern void SetCurrentProcessExplicitAppUserModelID( + [MarshalAs(UnmanagedType.LPWStr)] string appId); + + public static WindowsApplicationContext FromCurrentProcess(string? customName = null, + string? appUserModelId = null) + { + var aumid = appUserModelId ?? Guid.NewGuid().ToString(); + + SetCurrentProcessExplicitAppUserModelID(aumid); + + var mainModule = Process.GetCurrentProcess().MainModule; + + using var shortcut = new ShellLink + { + TargetPath = mainModule.FileName, + Arguments = string.Empty, + AppUserModelID = aumid + }; + + var appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + var startMenuPath = Path.Combine(appData, @"Microsoft\Windows\Start Menu\Programs"); + var appName = customName ?? Path.GetFileNameWithoutExtension(mainModule.FileName); + var shortcutFile = Path.Combine(startMenuPath, $"{appName}.lnk"); + + shortcut.Save(shortcutFile); + + return new WindowsApplicationContext(appName, aumid); + } + } +} \ No newline at end of file diff --git a/DesktopNotifications.Windows/WindowsNotificationManager.cs b/DesktopNotifications.Windows/WindowsNotificationManager.cs index 66169bd..1f23cf2 100644 --- a/DesktopNotifications.Windows/WindowsNotificationManager.cs +++ b/DesktopNotifications.Windows/WindowsNotificationManager.cs @@ -10,6 +10,7 @@ namespace DesktopNotifications.Windows { public class WindowsNotificationManager : INotificationManager { + private readonly WindowsApplicationContext _applicationContext; private readonly Dictionary _notifications; private readonly ToastNotifier _toastNotifier; private string? _launchAction; @@ -18,10 +19,11 @@ namespace DesktopNotifications.Windows /// /// - /// - public WindowsNotificationManager(string appId) + /// + public WindowsNotificationManager(WindowsApplicationContext? applicationContext = null) { - _toastNotifier = ToastNotificationManager.CreateToastNotifier(appId); + _applicationContext = applicationContext ?? WindowsApplicationContext.FromCurrentProcess(); + _toastNotifier = ToastNotificationManager.CreateToastNotifier(_applicationContext.AppUserModelId); _notifications = new Dictionary(); } diff --git a/DesktopNotifications/ApplicationContext.cs b/DesktopNotifications/ApplicationContext.cs new file mode 100644 index 0000000..6afc75e --- /dev/null +++ b/DesktopNotifications/ApplicationContext.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace DesktopNotifications +{ + /// + /// + /// + public class ApplicationContext + { + public ApplicationContext(string name) + { + Name = name; + } + + /// + /// + /// + public string Name { get; } + + } +} diff --git a/Example/Program.cs b/Example/Program.cs index 9417de6..88f0bc9 100644 --- a/Example/Program.cs +++ b/Example/Program.cs @@ -1,12 +1,9 @@ using System; -using System.Diagnostics; -using System.IO; using System.Runtime.InteropServices; using System.Threading.Tasks; using DesktopNotifications; using DesktopNotifications.FreeDesktop; using DesktopNotifications.Windows; -using Example.Win32; namespace Example { @@ -25,24 +22,7 @@ namespace Example if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - const string AppName = "DesktopNotificationsExample"; - - SetCurrentProcessExplicitAppUserModelID(AppName); - - using var shortcut = new ShellLink - { - TargetPath = Process.GetCurrentProcess().MainModule.FileName, - Arguments = string.Empty, - AppUserModelID = AppName - }; - - var appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); - var startMenuPath = Path.Combine(appData, @"Microsoft\Windows\Start Menu\Programs"); - var shortcutFile = Path.Combine(startMenuPath, $"{AppName}.lnk"); - - shortcut.Save(shortcutFile); - - return new WindowsNotificationManager(AppName); + return new WindowsNotificationManager(); } throw new PlatformNotSupportedException();