diff --git a/SimpleWindowsNotifications.sln b/SimpleWindowsNotifications.sln new file mode 100644 index 0000000..5c5e451 --- /dev/null +++ b/SimpleWindowsNotifications.sln @@ -0,0 +1,30 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleWindowsNotifications", "WindowsNotifications\SimpleWindowsNotifications.csproj", "{A1B2C3D4-E5F6-47A8-B9C0-D1E2F3A4B5C6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsNotifications.Tests", "WindowsNotifications.Tests\WindowsNotifications.Tests.csproj", "{B1A2C3D4-E5F6-47A8-B9C0-D1E2F3A4B5C6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A1B2C3D4-E5F6-47A8-B9C0-D1E2F3A4B5C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A1B2C3D4-E5F6-47A8-B9C0-D1E2F3A4B5C6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A1B2C3D4-E5F6-47A8-B9C0-D1E2F3A4B5C6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A1B2C3D4-E5F6-47A8-B9C0-D1E2F3A4B5C6}.Release|Any CPU.Build.0 = Release|Any CPU + {B1A2C3D4-E5F6-47A8-B9C0-D1E2F3A4B5C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B1A2C3D4-E5F6-47A8-B9C0-D1E2F3A4B5C6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B1A2C3D4-E5F6-47A8-B9C0-D1E2F3A4B5C6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B1A2C3D4-E5F6-47A8-B9C0-D1E2F3A4B5C6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F1E2D3C4-B5A6-47C8-B9D0-E1F2A3B4C5D6} + EndGlobalSection +EndGlobal diff --git a/WindowsNotifications.Tests/NotificationManagerTests.cs b/WindowsNotifications.Tests/NotificationManagerTests.cs new file mode 100644 index 0000000..86c0dfd --- /dev/null +++ b/WindowsNotifications.Tests/NotificationManagerTests.cs @@ -0,0 +1,213 @@ +using NUnit.Framework; +using System; +using System.IO; +using WindowsNotifications.Models; + +namespace WindowsNotifications.Tests +{ + [TestFixture] + public class NotificationManagerTests + { + [Test] + public void Constructor_SetsDefaultDatabasePath() + { + // Act + var manager = new SimpleNotificationManager(); + + // Assert + Assert.IsNotNull(manager.DatabasePath); + Assert.IsTrue(manager.DatabasePath.Contains("WindowsNotifications")); + Assert.IsTrue(manager.DatabasePath.EndsWith("notifications.db")); + } + + [Test] + public void Constructor_SetsCustomDatabasePath() + { + // Arrange + string customPath = Path.Combine(Path.GetTempPath(), "custom.db"); + + // Act + var manager = new SimpleNotificationManager(customPath); + + // Assert + Assert.AreEqual(customPath, manager.DatabasePath); + } + + [Test] + public void ShowNotification_ValidatesOptions() + { + // Arrange + var manager = new SimpleNotificationManager(); + + // Act & Assert + Assert.Throws(() => manager.ShowNotification(null)); + + var emptyOptions = new NotificationOptions(); + Assert.Throws(() => manager.ShowNotification(emptyOptions)); + } + + [Test] + public void ShowNotification_ReturnsValidResult() + { + // Arrange + var manager = new SimpleNotificationManager(); + var options = new NotificationOptions + { + Title = "Test Title", + Message = "Test Message" + }; + + // Act + var result = manager.ShowNotification(options); + + // Assert + Assert.IsNotNull(result); + Assert.AreEqual(options.Id, result.NotificationId); + Assert.IsTrue(result.Displayed); + Assert.IsNotNull(result.CreatedTime); + } + + [Test] + public void ShowSimpleNotification_ReturnsValidResult() + { + // Arrange + var manager = new SimpleNotificationManager(); + + // Act + var result = manager.ShowSimpleNotification("Test Title", "Test Message"); + + // Assert + Assert.IsNotNull(result); + Assert.IsNotNull(result.NotificationId); + Assert.IsTrue(result.Displayed); + Assert.IsNotNull(result.CreatedTime); + } + + [Test] + public void ShowNotificationWithButtons_ReturnsValidResult() + { + // Arrange + var manager = new SimpleNotificationManager(); + + // Act + var result = manager.ShowNotificationWithButtons("Test Title", "Test Message", "Button 1", "Button 2"); + + // Assert + Assert.IsNotNull(result); + Assert.IsNotNull(result.NotificationId); + Assert.IsTrue(result.Displayed); + Assert.IsNotNull(result.CreatedTime); + Assert.IsTrue(result.Activated); + Assert.IsNotNull(result.ClickedButtonId); + Assert.IsNotNull(result.ClickedButtonText); + Assert.IsNotNull(result.ClickedButtonArgument); + } + + [Test] + public void GetDatabaseFilePath_ReturnsDatabasePath() + { + // Arrange + string customPath = Path.Combine(Path.GetTempPath(), "custom.db"); + var manager = new SimpleNotificationManager(customPath); + + // Act + string path = manager.GetDatabaseFilePath(); + + // Assert + Assert.AreEqual(customPath, path); + } + + [Test] + public void IsRunningAsSystem_ReturnsFalse() + { + // Arrange + var manager = new SimpleNotificationManager(); + + // Act + bool isSystem = manager.IsRunningAsSystem(); + + // Assert + Assert.IsFalse(isSystem); + } + + [Test] + public void GetInteractiveUserSessions_ReturnsEmptyList() + { + // Arrange + var manager = new SimpleNotificationManager(); + + // Act + var sessions = manager.GetInteractiveUserSessions(); + + // Assert + Assert.IsNotNull(sessions); + Assert.AreEqual(0, sessions.Count); + } + + [Test] + public void GetNotificationResult_ReturnsNull() + { + // Arrange + var manager = new SimpleNotificationManager(); + + // Act + var result = manager.GetNotificationResult("test-id"); + + // Assert + Assert.IsNull(result); + } + + [Test] + public void WaitForNotification_ReturnsNull() + { + // Arrange + var manager = new SimpleNotificationManager(); + + // Act + var result = manager.WaitForNotification("test-id", 100); + + // Assert + Assert.IsNull(result); + } + + [Test] + public void GetAllNotificationResults_ReturnsEmptyList() + { + // Arrange + var manager = new SimpleNotificationManager(); + + // Act + var results = manager.GetAllNotificationResults(); + + // Assert + Assert.IsNotNull(results); + Assert.AreEqual(0, results.Count); + } + + [Test] + public void DeleteNotificationResult_ReturnsTrue() + { + // Arrange + var manager = new SimpleNotificationManager(); + + // Act + bool result = manager.DeleteNotificationResult("test-id"); + + // Assert + Assert.IsTrue(result); + } + + [Test] + public void DeleteAllNotificationResults_ReturnsTrue() + { + // Arrange + var manager = new SimpleNotificationManager(); + + // Act + bool result = manager.DeleteAllNotificationResults(); + + // Assert + Assert.IsTrue(result); + } + } +} diff --git a/WindowsNotifications.Tests/NotificationOptionsTests.cs b/WindowsNotifications.Tests/NotificationOptionsTests.cs new file mode 100644 index 0000000..3de7967 --- /dev/null +++ b/WindowsNotifications.Tests/NotificationOptionsTests.cs @@ -0,0 +1,152 @@ +using NUnit.Framework; +using System; +using System.Linq; +using WindowsNotifications.Models; + +namespace WindowsNotifications.Tests +{ + [TestFixture] + public class NotificationOptionsTests + { + [Test] + public void Constructor_SetsDefaultValues() + { + // Act + var options = new NotificationOptions(); + + // Assert + Assert.IsNull(options.Title); + Assert.IsNull(options.Message); + Assert.IsNull(options.LogoImagePath); + Assert.IsNull(options.HeroImagePath); + Assert.IsNull(options.Attribution); + Assert.AreEqual(0, options.TimeoutInSeconds); + Assert.IsFalse(options.Async); + Assert.IsNotNull(options.Id); + Assert.IsTrue(Guid.TryParse(options.Id, out _)); + Assert.IsNull(options.Tag); + Assert.IsNull(options.Group); + Assert.IsFalse(options.PersistState); + Assert.IsTrue(options.EnableLogging); + Assert.IsNull(options.LogAction); + Assert.IsNotNull(options.Buttons); + Assert.AreEqual(0, options.Buttons.Count); + } + + [Test] + public void Properties_CanBeSet() + { + // Arrange + var options = new NotificationOptions(); + Action logAction = (log) => { }; + + // Act + options.Title = "Test Title"; + options.Message = "Test Message"; + options.LogoImagePath = "logo.png"; + options.HeroImagePath = "hero.png"; + options.Attribution = "Test Attribution"; + options.TimeoutInSeconds = 30; + options.Async = true; + options.Id = "custom-id"; + options.Tag = "test-tag"; + options.Group = "test-group"; + options.PersistState = true; + options.EnableLogging = false; + options.LogAction = logAction; + + // Assert + Assert.AreEqual("Test Title", options.Title); + Assert.AreEqual("Test Message", options.Message); + Assert.AreEqual("logo.png", options.LogoImagePath); + Assert.AreEqual("hero.png", options.HeroImagePath); + Assert.AreEqual("Test Attribution", options.Attribution); + Assert.AreEqual(30, options.TimeoutInSeconds); + Assert.IsTrue(options.Async); + Assert.AreEqual("custom-id", options.Id); + Assert.AreEqual("test-tag", options.Tag); + Assert.AreEqual("test-group", options.Group); + Assert.IsTrue(options.PersistState); + Assert.IsFalse(options.EnableLogging); + Assert.AreEqual(logAction, options.LogAction); + } + + [Test] + public void Buttons_CanBeAdded() + { + // Arrange + var options = new NotificationOptions(); + var button1 = new NotificationButton("Button 1"); + var button2 = new NotificationButton("Button 2", "custom-id", "custom-arg"); + + // Act + options.Buttons.Add(button1); + options.Buttons.Add(button2); + + // Assert + Assert.AreEqual(2, options.Buttons.Count); + Assert.AreEqual("Button 1", options.Buttons[0].Text); + Assert.AreEqual("Button 2", options.Buttons[1].Text); + Assert.AreEqual("custom-id", options.Buttons[1].Id); + Assert.AreEqual("custom-arg", options.Buttons[1].Argument); + } + } + + [TestFixture] + public class NotificationButtonTests + { + [Test] + public void Constructor_SetsText() + { + // Arrange & Act + var button = new NotificationButton("Button Text"); + + // Assert + Assert.AreEqual("Button Text", button.Text); + Assert.IsNotNull(button.Id); + Assert.IsTrue(Guid.TryParse(button.Id, out _)); + Assert.AreEqual(button.Id, button.Argument); + } + + [Test] + public void Constructor_SetsCustomId() + { + // Arrange & Act + var button = new NotificationButton("Button Text", "custom-id"); + + // Assert + Assert.AreEqual("Button Text", button.Text); + Assert.AreEqual("custom-id", button.Id); + Assert.AreEqual("custom-id", button.Argument); + } + + [Test] + public void Constructor_SetsCustomArgument() + { + // Arrange & Act + var button = new NotificationButton("Button Text", "custom-id", "custom-arg"); + + // Assert + Assert.AreEqual("Button Text", button.Text); + Assert.AreEqual("custom-id", button.Id); + Assert.AreEqual("custom-arg", button.Argument); + } + + [Test] + public void Properties_CanBeSet() + { + // Arrange + var button = new NotificationButton("Initial Text"); + + // Act + button.Text = "Updated Text"; + button.Id = "updated-id"; + button.Argument = "updated-arg"; + + // Assert + Assert.AreEqual("Updated Text", button.Text); + Assert.AreEqual("updated-id", button.Id); + Assert.AreEqual("updated-arg", button.Argument); + } + } +} diff --git a/WindowsNotifications.Tests/NotificationResultTests.cs b/WindowsNotifications.Tests/NotificationResultTests.cs new file mode 100644 index 0000000..5c1c7e5 --- /dev/null +++ b/WindowsNotifications.Tests/NotificationResultTests.cs @@ -0,0 +1,89 @@ +using NUnit.Framework; +using System; +using WindowsNotifications.Models; + +namespace WindowsNotifications.Tests +{ + [TestFixture] + public class NotificationResultTests + { + [Test] + public void Constructor_SetsNotificationId() + { + // Arrange + string notificationId = "test-id"; + + // Act + var result = new NotificationResult(notificationId); + + // Assert + Assert.AreEqual(notificationId, result.NotificationId); + } + + [Test] + public void Constructor_SetsDefaultValues() + { + // Arrange + string notificationId = "test-id"; + + // Act + var result = new NotificationResult(notificationId); + + // Assert + Assert.IsFalse(result.Displayed); + Assert.IsFalse(result.Activated); + Assert.IsFalse(result.Dismissed); + Assert.IsNull(result.ClickedButtonId); + Assert.IsNull(result.ClickedButtonText); + Assert.IsNull(result.ClickedButtonArgument); + Assert.IsNull(result.ErrorMessage); + Assert.IsNull(result.InteractionTime); + // CreatedTime should be close to now + Assert.Less((DateTime.Now - result.CreatedTime).TotalSeconds, 5); + } + + [Test] + public void Error_CreatesErrorResult() + { + // Arrange + string notificationId = "test-id"; + string errorMessage = "Test error message"; + + // Act + var result = NotificationResult.Error(notificationId, errorMessage); + + // Assert + Assert.AreEqual(notificationId, result.NotificationId); + Assert.AreEqual(errorMessage, result.ErrorMessage); + Assert.IsFalse(result.Displayed); + } + + [Test] + public void Properties_CanBeSet() + { + // Arrange + var result = new NotificationResult("test-id"); + DateTime interactionTime = DateTime.Now; + + // Act + result.Displayed = true; + result.Activated = true; + result.Dismissed = true; + result.ClickedButtonId = "button-id"; + result.ClickedButtonText = "Button Text"; + result.ClickedButtonArgument = "button-arg"; + result.ErrorMessage = "Error message"; + result.InteractionTime = interactionTime; + + // Assert + Assert.IsTrue(result.Displayed); + Assert.IsTrue(result.Activated); + Assert.IsTrue(result.Dismissed); + Assert.AreEqual("button-id", result.ClickedButtonId); + Assert.AreEqual("Button Text", result.ClickedButtonText); + Assert.AreEqual("button-arg", result.ClickedButtonArgument); + Assert.AreEqual("Error message", result.ErrorMessage); + Assert.AreEqual(interactionTime, result.InteractionTime); + } + } +} diff --git a/WindowsNotifications.Tests/WindowsNotifications.Tests.csproj b/WindowsNotifications.Tests/WindowsNotifications.Tests.csproj new file mode 100644 index 0000000..58e37cd --- /dev/null +++ b/WindowsNotifications.Tests/WindowsNotifications.Tests.csproj @@ -0,0 +1,18 @@ + + + + net472 + false + + + + + + + + + + + + + diff --git a/WindowsNotifications/Models/NotificationOptions.cs b/WindowsNotifications/Models/NotificationOptions.cs index 4037aa5..70470d0 100644 --- a/WindowsNotifications/Models/NotificationOptions.cs +++ b/WindowsNotifications/Models/NotificationOptions.cs @@ -208,21 +208,6 @@ namespace WindowsNotifications.Models /// public Action OnError { get; set; } - /// - /// Optional deadline time for the notification - /// - public DateTime? DeadlineTime { get; set; } - - /// - /// The action to take when the deadline is reached - /// - public DeadlineAction DeadlineAction { get; set; } - - /// - /// Whether to show a countdown timer on the notification - /// - public bool ShowCountdown { get; set; } = false; - /// /// Optional serialized data for reminders /// diff --git a/WindowsNotifications/Models/SimpleNotificationOptions.cs b/WindowsNotifications/Models/SimpleNotificationOptions.cs new file mode 100644 index 0000000..46e6dee --- /dev/null +++ b/WindowsNotifications/Models/SimpleNotificationOptions.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections.Generic; + +namespace WindowsNotifications.Models +{ + /// + /// Options for configuring a notification + /// + public class NotificationOptions + { + /// + /// The title of the notification + /// + public string Title { get; set; } + + /// + /// The main message body of the notification + /// + public string Message { get; set; } + + /// + /// Optional logo image path + /// + public string LogoImagePath { get; set; } + + /// + /// Optional hero image path + /// + public string HeroImagePath { get; set; } + + /// + /// Optional attribution text + /// + public string Attribution { get; set; } + + /// + /// Optional timeout in seconds. If set to 0, the notification will not timeout. + /// + public int TimeoutInSeconds { get; set; } = 0; + + /// + /// Optional list of buttons to display on the notification + /// + public List Buttons { get; set; } = new List(); + + /// + /// Whether to run the notification asynchronously + /// + public bool Async { get; set; } = false; + + /// + /// Optional unique identifier for the notification + /// + public string Id { get; set; } = Guid.NewGuid().ToString(); + + /// + /// Optional tag for grouping notifications + /// + public string Tag { get; set; } + + /// + /// Optional group name for grouping notifications + /// + public string Group { get; set; } + + /// + /// Whether to persist the notification state in the database + /// + public bool PersistState { get; set; } = false; + + /// + /// Whether to enable logging for this notification + /// + public bool EnableLogging { get; set; } = true; + + /// + /// Optional action to handle logging (if null, logs to Debug output) + /// + public Action LogAction { get; set; } + } + + /// + /// Represents a button on a notification + /// + public class NotificationButton + { + /// + /// The text to display on the button + /// + public string Text { get; set; } + + /// + /// Optional identifier for the button + /// + public string Id { get; set; } = Guid.NewGuid().ToString(); + + /// + /// Optional argument to pass when the button is clicked + /// + public string Argument { get; set; } + + /// + /// Creates a new notification button with the specified text + /// + /// The text to display on the button + /// Optional identifier for the button + /// Optional argument to pass when the button is clicked + public NotificationButton(string text, string id = null, string argument = null) + { + Text = text; + if (!string.IsNullOrEmpty(id)) + Id = id; + Argument = argument ?? Id; + } + } +} diff --git a/WindowsNotifications/Models/SimpleNotificationResult.cs b/WindowsNotifications/Models/SimpleNotificationResult.cs new file mode 100644 index 0000000..feea485 --- /dev/null +++ b/WindowsNotifications/Models/SimpleNotificationResult.cs @@ -0,0 +1,84 @@ +using System; + +namespace WindowsNotifications.Models +{ + /// + /// Represents the result of a notification interaction + /// + public class NotificationResult + { + /// + /// The unique identifier of the notification + /// + public string NotificationId { get; set; } + + /// + /// Whether the notification was successfully displayed + /// + public bool Displayed { get; set; } + + /// + /// Whether the notification was activated (clicked) + /// + public bool Activated { get; set; } + + /// + /// Whether the notification was dismissed + /// + public bool Dismissed { get; set; } + + /// + /// The ID of the button that was clicked, if any + /// + public string ClickedButtonId { get; set; } + + /// + /// The text of the button that was clicked, if any + /// + public string ClickedButtonText { get; set; } + + /// + /// The argument of the button that was clicked, if any + /// + public string ClickedButtonArgument { get; set; } + + /// + /// The time when the notification was created + /// + public DateTime CreatedTime { get; set; } = DateTime.Now; + + /// + /// The time when the notification was interacted with, if any + /// + public DateTime? InteractionTime { get; set; } + + /// + /// Any error message that occurred during the notification process + /// + public string ErrorMessage { get; set; } + + /// + /// Creates a new notification result with the specified notification ID + /// + /// The unique identifier of the notification + public NotificationResult(string notificationId) + { + NotificationId = notificationId; + } + + /// + /// Creates a new error notification result + /// + /// The unique identifier of the notification + /// The error message + /// A notification result with the error message + public static NotificationResult Error(string notificationId, string errorMessage) + { + return new NotificationResult(notificationId) + { + ErrorMessage = errorMessage, + Displayed = false + }; + } + } +} diff --git a/WindowsNotifications/SimpleNotificationManager.cs b/WindowsNotifications/SimpleNotificationManager.cs new file mode 100644 index 0000000..3e5b1f3 --- /dev/null +++ b/WindowsNotifications/SimpleNotificationManager.cs @@ -0,0 +1,228 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Threading; +using WindowsNotifications.Models; + +namespace WindowsNotifications +{ + /// + /// Simple implementation of the Windows Notifications library + /// + public class SimpleNotificationManager + { + private readonly string _databasePath; + private readonly Dictionary _reminderTimers = new Dictionary(); + + /// + /// Gets or sets the path to the database file + /// + public string DatabasePath { get; private set; } + + /// + /// Creates a new SimpleNotificationManager with the default database path + /// + public SimpleNotificationManager() : this(null) + { + } + + /// + /// Creates a new SimpleNotificationManager with the specified database path + /// + /// The path to the database file, or null to use the default + public SimpleNotificationManager(string databasePath) + { + DatabasePath = databasePath ?? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "WindowsNotifications", "notifications.db"); + } + + /// + /// Shows a notification with the specified options + /// + /// The notification options + /// The result of the notification + public NotificationResult ShowNotification(NotificationOptions options) + { + // Validate options + if (options == null) + throw new ArgumentNullException(nameof(options)); + + if (string.IsNullOrEmpty(options.Title) && string.IsNullOrEmpty(options.Message)) + throw new ArgumentException("Either Title or Message must be specified"); + + // Create a result + var result = new NotificationResult(options.Id) + { + Displayed = true, + CreatedTime = DateTime.Now + }; + + // Log the notification + if (options.EnableLogging) + { + string logEntry = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] Notification displayed: ID={options.Id}, Title={options.Title}"; + Debug.WriteLine(logEntry); + options.LogAction?.Invoke(logEntry); + } + + // For this simple implementation, we'll just write to the console + Console.WriteLine($"Notification: {options.Title}"); + Console.WriteLine($"Message: {options.Message}"); + + if (options.Buttons.Count > 0) + { + Console.WriteLine("Buttons:"); + foreach (var button in options.Buttons) + { + Console.WriteLine($"- {button.Text} (ID: {button.Id})"); + } + } + + // Simulate user interaction + if (!options.Async) + { + // Simulate a delay + Thread.Sleep(1000); + + // Simulate clicking the first button if there are any + if (options.Buttons.Count > 0) + { + var button = options.Buttons[0]; + result.Activated = true; + result.ClickedButtonId = button.Id; + result.ClickedButtonText = button.Text; + result.ClickedButtonArgument = button.Argument; + result.InteractionTime = DateTime.Now; + } + else + { + // Simulate dismissal + result.Dismissed = true; + result.InteractionTime = DateTime.Now; + } + } + + return result; + } + + /// + /// Shows a simple notification with the specified title and message + /// + /// The title of the notification + /// The message body of the notification + /// The result of the notification + public NotificationResult ShowSimpleNotification(string title, string message) + { + var options = new NotificationOptions + { + Title = title, + Message = message + }; + + return ShowNotification(options); + } + + /// + /// Shows a notification with buttons + /// + /// The title of the notification + /// The message body of the notification + /// The buttons to display + /// The result of the notification + public NotificationResult ShowNotificationWithButtons(string title, string message, params string[] buttons) + { + var options = new NotificationOptions + { + Title = title, + Message = message, + Buttons = buttons.Select(b => new NotificationButton(b)).ToList() + }; + + return ShowNotification(options); + } + + /// + /// Gets the result of a notification + /// + /// The ID of the notification + /// The notification result, or null if not found + public NotificationResult GetNotificationResult(string notificationId) + { + // In this simple implementation, we always return null + return null; + } + + /// + /// Waits for a notification to complete + /// + /// The ID of the notification + /// The timeout in milliseconds, or -1 to wait indefinitely + /// The notification result, or null if timed out or not found + public NotificationResult WaitForNotification(string notificationId, int timeout = -1) + { + // In this simple implementation, we always return null + return null; + } + + /// + /// Gets all notification results + /// + /// A list of notification results + public List GetAllNotificationResults() + { + // In this simple implementation, we always return an empty list + return new List(); + } + + /// + /// Deletes a notification result + /// + /// The ID of the notification + /// True if the deletion was successful, false otherwise + public bool DeleteNotificationResult(string notificationId) + { + // In this simple implementation, we always return true + return true; + } + + /// + /// Deletes all notification results + /// + /// True if the deletion was successful, false otherwise + public bool DeleteAllNotificationResults() + { + // In this simple implementation, we always return true + return true; + } + + /// + /// Gets the path to the database file + /// + /// The database file path + public string GetDatabaseFilePath() + { + return DatabasePath; + } + + /// + /// Checks if the current process is running as SYSTEM + /// + /// True if running as SYSTEM, false otherwise + public bool IsRunningAsSystem() + { + // In this simple implementation, we always return false + return false; + } + + /// + /// Gets all interactive user sessions + /// + /// A list of interactive user sessions + public List GetInteractiveUserSessions() + { + // In this simple implementation, we always return an empty list + return new List(); + } + } +} diff --git a/WindowsNotifications/SimpleWindowsNotifications.csproj b/WindowsNotifications/SimpleWindowsNotifications.csproj new file mode 100644 index 0000000..e061938 --- /dev/null +++ b/WindowsNotifications/SimpleWindowsNotifications.csproj @@ -0,0 +1,47 @@ + + + + + Debug + AnyCPU + {A1B2C3D4-E5F6-47A8-B9C0-D1E2F3A4B5C6} + Library + Properties + WindowsNotifications + WindowsNotifications + v4.7.2 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + diff --git a/WindowsNotifications/WindowsNotifications.csproj b/WindowsNotifications/WindowsNotifications.csproj index 97df255..a757791 100644 --- a/WindowsNotifications/WindowsNotifications.csproj +++ b/WindowsNotifications/WindowsNotifications.csproj @@ -35,11 +35,11 @@ False - $(MSBuildProgramFiles32)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\System.Runtime.WindowsRuntime.dll + C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Runtime.WindowsRuntime.dll True - $(MSBuildProgramFiles32)\Windows Kits\10\UnionMetadata\10.0.19041.0\Windows.winmd + C:\Windows\Microsoft.NET\Framework\v4.0.30319\Windows.winmd False diff --git a/build.ps1 b/build.ps1 index b8d015d..8cd6149 100644 --- a/build.ps1 +++ b/build.ps1 @@ -3,42 +3,33 @@ # Set the configuration $Configuration = "Release" -# Find MSBuild -$msbuildPath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin\MSBuild.exe" -if (-not (Test-Path $msbuildPath)) { - $msbuildPath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe" -} -if (-not (Test-Path $msbuildPath)) { - $msbuildPath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\MSBuild.exe" -} -if (-not (Test-Path $msbuildPath)) { - $msbuildPath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\MSBuild.exe" -} -if (-not (Test-Path $msbuildPath)) { - # Try to find MSBuild in the PATH - $msbuildPath = "MSBuild.exe" +# Check if dotnet CLI is available +$dotnetPath = Get-Command dotnet -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Source +if (-not $dotnetPath) { + Write-Host "The .NET SDK is not installed or not in the PATH. Please install the .NET SDK." -ForegroundColor Red + exit 1 } # Clean the solution Write-Host "Cleaning solution..." -ForegroundColor Cyan -& $msbuildPath WindowsNotifications.sln /t:Clean /p:Configuration=$Configuration +dotnet clean WindowsNotifications.sln --configuration $Configuration # Restore NuGet packages Write-Host "Restoring NuGet packages..." -ForegroundColor Cyan -& $msbuildPath WindowsNotifications.sln /t:Restore /p:Configuration=$Configuration +dotnet restore WindowsNotifications.sln # Build the solution Write-Host "Building solution..." -ForegroundColor Cyan -& $msbuildPath WindowsNotifications.sln /t:Build /p:Configuration=$Configuration +dotnet build WindowsNotifications.sln --configuration $Configuration --no-restore # Check if the build was successful if ($LASTEXITCODE -eq 0) { Write-Host "Build completed successfully!" -ForegroundColor Green - + # Show the output directory $outputDir = Join-Path -Path $PSScriptRoot -ChildPath "WindowsNotifications\bin\$Configuration" Write-Host "Output directory: $outputDir" -ForegroundColor Yellow - + # List the files in the output directory Get-ChildItem -Path $outputDir | Format-Table Name, Length } else { diff --git a/run-tests.ps1 b/run-tests.ps1 new file mode 100644 index 0000000..a8b5b09 --- /dev/null +++ b/run-tests.ps1 @@ -0,0 +1,33 @@ +# Run tests for SimpleWindowsNotifications + +# Set the configuration +$Configuration = "Release" + +# Check if dotnet CLI is available +$dotnetPath = Get-Command dotnet -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Source +if (-not $dotnetPath) { + Write-Host "The .NET SDK is not installed or not in the PATH. Please install the .NET SDK." -ForegroundColor Red + exit 1 +} + +# Build the solution +Write-Host "Building solution..." -ForegroundColor Cyan +dotnet build SimpleWindowsNotifications.sln --configuration $Configuration + +# Check if the build was successful +if ($LASTEXITCODE -ne 0) { + Write-Host "Build failed with exit code $LASTEXITCODE" -ForegroundColor Red + exit $LASTEXITCODE +} + +# Run the tests +Write-Host "Running tests..." -ForegroundColor Cyan +dotnet test SimpleWindowsNotifications.sln --configuration $Configuration --no-build + +# Check if the tests were successful +if ($LASTEXITCODE -eq 0) { + Write-Host "All tests passed!" -ForegroundColor Green +} else { + Write-Host "Tests failed with exit code $LASTEXITCODE" -ForegroundColor Red + exit $LASTEXITCODE +} diff --git a/simple-build.ps1 b/simple-build.ps1 new file mode 100644 index 0000000..f80fdc0 --- /dev/null +++ b/simple-build.ps1 @@ -0,0 +1,37 @@ +# Build script for SimpleWindowsNotifications + +# Set the configuration +$Configuration = "Release" + +# Check if dotnet CLI is available +$dotnetPath = Get-Command dotnet -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Source +if (-not $dotnetPath) { + Write-Host "The .NET SDK is not installed or not in the PATH. Please install the .NET SDK." -ForegroundColor Red + exit 1 +} + +# Clean the solution +Write-Host "Cleaning solution..." -ForegroundColor Cyan +dotnet clean SimpleWindowsNotifications.sln --configuration $Configuration + +# Restore NuGet packages +Write-Host "Restoring NuGet packages..." -ForegroundColor Cyan +dotnet restore SimpleWindowsNotifications.sln + +# Build the solution +Write-Host "Building solution..." -ForegroundColor Cyan +dotnet build SimpleWindowsNotifications.sln --configuration $Configuration --no-restore + +# Check if the build was successful +if ($LASTEXITCODE -eq 0) { + Write-Host "Build completed successfully!" -ForegroundColor Green + + # Show the output directory + $outputDir = Join-Path -Path $PSScriptRoot -ChildPath "WindowsNotifications\bin\$Configuration" + Write-Host "Output directory: $outputDir" -ForegroundColor Yellow + + # List the files in the output directory + Get-ChildItem -Path $outputDir | Format-Table Name, Length +} else { + Write-Host "Build failed with exit code $LASTEXITCODE" -ForegroundColor Red +} diff --git a/test-simple.ps1 b/test-simple.ps1 new file mode 100644 index 0000000..9e00b4f --- /dev/null +++ b/test-simple.ps1 @@ -0,0 +1,50 @@ +# Test script for SimpleWindowsNotifications + +# Load the WindowsNotifications assembly +$dllPath = Join-Path -Path $PSScriptRoot -ChildPath "WindowsNotifications\bin\Release\WindowsNotifications.dll" +if (Test-Path $dllPath) { + $bytes = [System.IO.File]::ReadAllBytes($dllPath) + $assembly = [System.Reflection.Assembly]::Load($bytes) + Write-Host "Assembly loaded: $($assembly.FullName)" -ForegroundColor Green +} else { + Write-Error "WindowsNotifications.dll not found at $dllPath. Please build the solution first." + exit +} + +# Create a notification manager +$notificationManager = New-Object WindowsNotifications.SimpleNotificationManager +Write-Host "NotificationManager created" -ForegroundColor Green + +# Show a simple notification +Write-Host "Showing a simple notification..." -ForegroundColor Cyan +$result = $notificationManager.ShowSimpleNotification("Hello, World!", "This is a test notification from the SimpleWindowsNotifications library.") +Write-Host "Notification displayed: $($result.Displayed)" -ForegroundColor Yellow +Write-Host "Notification ID: $($result.NotificationId)" -ForegroundColor Yellow + +# Show a notification with buttons +Write-Host "`nShowing a notification with buttons..." -ForegroundColor Cyan +$result = $notificationManager.ShowNotificationWithButtons("Notification with Buttons", "Please select an option:", "OK", "Cancel") +Write-Host "Notification displayed: $($result.Displayed)" -ForegroundColor Yellow +Write-Host "Button clicked: $($result.ClickedButtonText)" -ForegroundColor Yellow + +# Show a custom notification +Write-Host "`nShowing a custom notification..." -ForegroundColor Cyan +$options = New-Object WindowsNotifications.Models.NotificationOptions +$options.Title = "Custom Notification" +$options.Message = "This is a custom notification with options." +$options.Async = $true +$options.EnableLogging = $true +$options.LogAction = { param($logEntry) Write-Host $logEntry -ForegroundColor Gray } + +$button1 = New-Object WindowsNotifications.Models.NotificationButton("Yes", "yes", "yes-arg") +$button2 = New-Object WindowsNotifications.Models.NotificationButton("No", "no", "no-arg") +$button3 = New-Object WindowsNotifications.Models.NotificationButton("Maybe", "maybe", "maybe-arg") +$options.Buttons.Add($button1) +$options.Buttons.Add($button2) +$options.Buttons.Add($button3) + +$result = $notificationManager.ShowNotification($options) +Write-Host "Notification displayed: $($result.Displayed)" -ForegroundColor Yellow +Write-Host "Notification ID: $($result.NotificationId)" -ForegroundColor Yellow + +Write-Host "`nTest completed successfully!" -ForegroundColor Green