diff --git a/src/ManagedShell.Common/Helpers/SoundHelper.cs b/src/ManagedShell.Common/Helpers/SoundHelper.cs
index 34a4c67e..382a7c34 100644
--- a/src/ManagedShell.Common/Helpers/SoundHelper.cs
+++ b/src/ManagedShell.Common/Helpers/SoundHelper.cs
@@ -8,12 +8,95 @@ namespace ManagedShell.Common.Helpers
public class SoundHelper
{
private const string SYSTEM_SOUND_ROOT_KEY = @"AppEvents\Schemes\Apps";
- private const int SND_FILENAME = 0x00020000;
- private const int SND_ASYNC = 0x0001;
- private const long SND_SYSTEM = 0x00200000L;
+
+ ///
+ /// Flag values for playing the sound.
+ ///
+ [Flags]
+ public enum SND : uint
+ {
+ ///
+ /// The sound is played synchronously; PlaySound returns after the sound event completes (default behavior).
+ ///
+ SYNC = 0x0000,
+
+ ///
+ /// The sound is played asynchronously; PlaySound returns immediately after initiating the sound.
+ /// To stop an asynchronously played sound, call PlaySound with pszSound set to NULL.
+ ///
+ ASYNC = 0x00000001,
+
+ ///
+ /// No default sound event is used. If the sound is not found, PlaySound returns without playing a sound.
+ ///
+ NODEFAULT = 0x00000002,
+
+ ///
+ /// The pszSound parameter points to a sound loaded in memory.
+ ///
+ MEMORY = 0x00000004,
+
+ ///
+ /// The sound plays repeatedly until PlaySound is called with pszSound set to NULL.
+ /// Use the ASYNC flag with LOOP.
+ ///
+ LOOP = 0x00000008,
+
+ ///
+ /// The specified sound event will yield to another sound event already playing in the same process.
+ /// If the required resource is busy, the function returns immediately without playing the sound.
+ ///
+ NOSTOP = 0x00000010,
+
+ ///
+ /// The pszSound parameter is a system-event alias from the registry or WIN.INI file.
+ /// Do not use with FILENAME or RESOURCE.
+ ///
+ ALIAS = 0x00010000,
+
+ ///
+ /// The pszSound parameter is a predefined identifier for a system-event alias.
+ ///
+ ALIAS_ID = 0x00110000,
+
+ ///
+ /// The pszSound parameter is a file name. If the file is not found, the default sound is played unless NODEFAULT is set.
+ ///
+ FILENAME = 0x00020000,
+
+ ///
+ /// The pszSound parameter is a resource identifier; hmod must identify the instance that contains the resource.
+ ///
+ RESOURCE = 0x00040004,
+
+ ///
+ /// The pszSound parameter is an application-specific alias in the registry.
+ /// Can be combined with ALIAS or ALIAS_ID to specify an application-defined sound alias.
+ ///
+ APPLICATION = 0x00000080,
+
+ ///
+ /// Requires Windows Vista or later. If set, triggers a SoundSentry event when the sound is played,
+ /// providing a visual cue for accessibility.
+ ///
+ SENTRY = 0x00080000,
+
+ ///
+ /// Treats the sound as a ring from a communications app.
+ ///
+ RING = 0x00100000,
+
+ ///
+ /// Requires Windows Vista or later. If set, the sound is assigned to the audio session for system notification sounds,
+ /// allowing control via the system volume slider. Otherwise, it is assigned to the application's default audio session.
+ ///
+ SYSTEM = 0x00200000,
+ }
+
+ private const SND DEFAULT_SYSTEM_SOUND_FLAGS = SND.ASYNC | SND.NODEFAULT | SND.SYSTEM;
[DllImport("winmm.dll", SetLastError = true, CharSet = CharSet.Auto)]
- private static extern bool PlaySound(string pszSound, IntPtr hmod, uint fdwSound);
+ public static extern bool PlaySound(string pszSound, IntPtr hmod, SND soundFlags);
///
/// Plays the specified system sound using the audio session for system notification sounds.
@@ -24,34 +107,42 @@ public static bool PlaySystemSound(string app, string name)
{
try
{
- using (RegistryKey key = Registry.CurrentUser.OpenSubKey($"{SYSTEM_SOUND_ROOT_KEY}\\{app}\\{name}\\.Current"))
+ using var key = Registry.CurrentUser.OpenSubKey($@"{SYSTEM_SOUND_ROOT_KEY}\{app}\{name}\.Current");
+ if (key == null)
+ {
+ ShellLogger.Debug($"SoundHelper: Unable to find sound {name} for app {app}");
+ return false;
+ }
+
+ var soundFileName = key.GetValue(null) as string;
+ if (string.IsNullOrEmpty(soundFileName))
{
- if (key == null)
- {
- ShellLogger.Error($"SoundHelper: Unable to find sound {name} for app {app}");
- return false;
- }
-
- if (key.GetValue(null) is string soundFileName)
- {
- if (string.IsNullOrEmpty(soundFileName))
- {
- ShellLogger.Error($"SoundHelper: Missing file for sound {name} for app {app}");
- return false;
- }
-
- return PlaySound(soundFileName, IntPtr.Zero, (uint)(SND_ASYNC | SND_FILENAME | SND_SYSTEM));
- }
- else
- {
- ShellLogger.Error($"SoundHelper: Missing file for sound {name} for app {app}");
- return false;
- }
+ ShellLogger.Debug($"SoundHelper: Missing file for sound {name} for app {app}");
+ return false;
}
+
+ return PlaySound(soundFileName, IntPtr.Zero, DEFAULT_SYSTEM_SOUND_FLAGS | SND.FILENAME);
}
catch (Exception e)
{
- ShellLogger.Error($"SoundHelper: Unable to play sound {name} for app {app}: {e.Message}");
+ ShellLogger.Debug($"SoundHelper: Unable to play sound {name} for app {app}: {e.Message}");
+ return false;
+ }
+ }
+
+ ///
+ /// Plays the specified system sound using the audio session for system notification sounds.
+ ///
+ /// The name of the system sound for ".Default" to play.
+ public static bool PlaySystemSound(string alias)
+ {
+ try
+ {
+ return PlaySound(alias, IntPtr.Zero, DEFAULT_SYSTEM_SOUND_FLAGS | SND.ALIAS);
+ }
+ catch (Exception e)
+ {
+ ShellLogger.Debug($"SoundHelper: Unable to play sound {alias}: {e.Message}");
return false;
}
}
@@ -62,24 +153,22 @@ public static bool PlaySystemSound(string app, string name)
public static void PlayNotificationSound()
{
// System default sound for the classic notification balloon.
- if (!PlaySystemSound("Explorer", "SystemNotification"))
+ if (PlaySystemSound("Explorer", "SystemNotification")) return;
+ if (EnvironmentHelper.IsWindows8OrBetter)
{
- if (EnvironmentHelper.IsWindows8OrBetter)
- {
- // Toast notification sound.
- if (!PlaySystemSound(".Default", "Notification.Default"))
- PlayXPNotificationSound();
- }
- else
- {
+ // Toast notification sound.
+ if (!PlaySystemSound("Notification.Default"))
PlayXPNotificationSound();
- }
+ }
+ else
+ {
+ PlayXPNotificationSound();
}
}
- public static bool PlayXPNotificationSound()
+ public static void PlayXPNotificationSound()
{
- return PlaySystemSound(".Default", "SystemNotification");
+ PlaySystemSound("SystemNotification");
}
}
}
\ No newline at end of file
diff --git a/src/ManagedShell.Common/ManagedShell.Common.csproj b/src/ManagedShell.Common/ManagedShell.Common.csproj
index 0409ff73..7998fdff 100644
--- a/src/ManagedShell.Common/ManagedShell.Common.csproj
+++ b/src/ManagedShell.Common/ManagedShell.Common.csproj
@@ -4,6 +4,7 @@
netcoreapp3.1;net471;net6.0-windows
true
true
+ 12