我需要从作为Windows服务运行的C#应用程序中播放wav文件。我已经尝试了System.Media.SoundPlayer和对WinMM.dll的P / Invoke调用(这可能是SoundPlayer正在做的事情)。
[DllImport("WinMM.dll")]
private static extern bool PlaySound(string fname, int Mod, int flag);
如果我将我的代码作为控制台应用程序运行,则声音会播放。当我从服务中运行它时,没有运气,我想我并不感到惊讶。
那么有没有办法从Windows服务播放声音? DirectSound会有帮助吗?或者我是否会被困在编写控制台应用程序并让Windows服务应用程序与它作为中介进行通信?
提前致谢
答案 0 :(得分:9)
通过使用Windows Core Audio API,至少在Windows 7(很可能是Vista)上播放来自服务的wav文件肯定是可能的。我最近通过使用NAudio制作小型测试服务来验证这一点。我刚刚下载了NAudio源并从他们的NAudioDemo项目中复制了“Wsapi”部分。这是在Windows 7企业版64位上,但我认为不重要。该服务使用的是LocalSystem帐户 为了记录,在嵌入式设置中播放来自服务的声音是完全合法的事情。
答案 1 :(得分:1)
应用NAudio只是为了播放音频文件 http://bresleveloper.blogspot.co.il/2012/06/c-service-play-sound-with-naudio.html
答案 2 :(得分:0)
您选择了错误的应用类型。 Windows服务适用于以非交互方式执行的较长时间运行的应用程序,无论是否有人登录到计算机。例如SQL Server,IIS等。
在Windows Vista及更高版本中,您也无法通过Windows服务显示用户界面窗口。对于Windows XP,2000 Server,您可以显示MessageBox,但不建议大多数服务使用。
因此,一般来说,服务不允许“互动”,包括播放声音,多媒体等。
您需要将应用程序类型更改为普通的控制台/ Windows窗体应用程序,或者在不播放服务声音的情况下直播。
有关详细信息,请参阅interactive services上的此页面以及MSDN上的相关页面。
答案 3 :(得分:0)
您可以通过Windows Vista或更高版本中的winmm.dll通过PlaySound API执行此操作。微软为“系统声音”添加了单独的会话。即使只是添加一个标志,它甚至可以从服务中使用。
我已经正确地格式化了这个,以避免c#2017 IDE在DllImport上摆动的问题不在名为' 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);
}
}
}