I need to play a wav file from a C# application running as a Windows Service. I have tried both System.Media.SoundPlayer and a P/Invoke call to WinMM.dll (which is probably what SoundPlayer is doing).
[DllImport("WinMM.dll")]
private static extern bool PlaySound(string fname, int Mod, int flag);
If I run my code as a console application, the sounds play. When I run it from a service, no luck, and I guess I'm not surprised.
So is there a way to play a sound from a windows service? Would something like DirectSound help? Or am I going to be stuck writing a console application and having the windows service app communicate with it as an intermediary?
Thanks in advance
Playing a wav file from a service is definitely possible, at least on Windows 7 (and most likely Vista), by using the Windows Core Audio APIs. I recently verified this by making a small test service using NAudio. I just downloaded the NAudio sources and copied the "Wsapi" parts from their NAudioDemo project. This was on Windows 7 Enterprise 64bit, but I don't think that matters. The service was using the LocalSystem account.
For the record, playing sounds from a service is a perfectly legitimate thing to do in an embedded setting.
You can do this via the PlaySound API via winmm.dll, in Windows Vista or above. Microsoft added a seperate session for 'System Sounds' that can be used even from services, by merely adding a flag.
I've formatted this properly to avoid issues with the c# 2017 IDE throwing a wobbly over the DllImport not being in a class named 'NativeMethods'.
using System.Runtime.InteropServices;
namespace Audio
{
internal static class NativeMethods
{
[DllImport("winmm.dll", EntryPoint = "PlaySound", SetLastError = true, CharSet = CharSet.Unicode, ThrowOnUnmappableChar = true)]
public static extern bool PlaySound(
string szSound,
System.IntPtr hMod,
PlaySoundFlags flags);
[System.Flags]
public enum PlaySoundFlags : int
{
SND_SYNC = 0x0000,/* play synchronously (default) */
SND_ASYNC = 0x0001, /* play asynchronously */
SND_NODEFAULT = 0x0002, /* silence (!default) if sound not found */
SND_MEMORY = 0x0004, /* pszSound points to a memory file */
SND_LOOP = 0x0008, /* loop the sound until next sndPlaySound */
SND_NOSTOP = 0x0010, /* don't stop any currently playing sound */
SND_NOWAIT = 0x00002000, /* don't wait if the driver is busy */
SND_ALIAS = 0x00010000,/* name is a registry alias */
SND_ALIAS_ID = 0x00110000, /* alias is a pre d ID */
SND_FILENAME = 0x00020000, /* name is file name */
SND_RESOURCE = 0x00040004, /* name is resource name or atom */
SND_PURGE = 0x0040, /* purge non-static events for task */
SND_APPLICATION = 0x0080, /* look for application specific association */
SND_SENTRY = 0x00080000, /* Generate a SoundSentry event with this sound */
SND_RING = 0x00100000, /* Treat this as a "ring" from a communications app - don't duck me */
SND_SYSTEM = 0x00200000 /* Treat this as a system sound */
}
}
public static class Play
{
public static void PlaySound(string path, string file = "")
{
NativeMethods.PlaySound(path + file, new System.IntPtr(), NativeMethods.PlaySoundFlags.SND_ASYNC | NativeMethods.PlaySoundFlags.SND_SYSTEM);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With