简体   繁体   English

System.Media.SoundPlayer在Windows Service应用程序中不起作用

[英]System.Media.SoundPlayer does not work in windows service applications

I have a simple service with the following code: 我有以下代码的简单服务:

on Program.Main method I have the code which is generated by vs itself(2010): 在Program.Main方法上,我有vs本身生成的代码(2010年):

static void Main()
    {
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] 
        { 
            new Service1() 
        };
        ServiceBase.Run(ServicesToRun);
    }

And in Service1.cs I have: 在Service1.cs中,我有:

 protected override void OnStart(string[] args)
    {
        System.Media.SoundPlayer myPlayer = new System.Media.SoundPlayer(@"C:\doorbell-1.wav");
        myPlayer.Play();
    }

    protected override void OnStop()
    {
    }

I have omit writing the usual automatically generated c# codes to reduce the complexity. 我省略了编写通常自动生成的C#代码以降低复杂性的步骤。

Logically a sound should be played when I start the service but nothing happens when I start the service. 从逻辑上讲,当我启动服务时应该播放声音,但是当我启动服务时什么也没有发生。 Please note that: 请注意:

1-I install the service using installUtill.exe. 1-我使用installUtill.exe安装服务。 2-The service runs under the localSystem account privilege. 2-该服务在localSystem帐户特权下运行。 3-Duration of the mentioned .wav file is 3Seconds. 提到的.wav文件的3个持续时间为3秒。

How can I play that sound? 如何播放声音? Thanks in advance. 提前致谢。

The simple answer is that you can't. 简单的答案是,你做不到。 Windows Services do not interact with the desktop, and thus they are not capable of using desktop functions like audio services. Windows服务不会与桌面交互,因此它们无法使用桌面功能,例如音频服务。

Remember, Windows is a multi-user operating system. 请记住,Windows是一个多用户操作系统。 Can you imagine what would happen if 5 simultaneously logged in users started playing audio? 您能想象如果同时登录的5个用户开始播放音频会发生什么情况?

All users have what's known as a "Windows Station", and there is a special Windows Station for the user logged into the physical computer. 所有用户都具有所谓的“ Windows Station”,并且有一个特殊的Windows Station供用户登录物理计算机。 Windows Services have a null or unique (non-interactive) Windows Station, and thus cannot interact with the console WS. Windows服务具有空的或唯一的(非交互式)Windows Station,因此无法与控制台WS进行交互。

This Windows Station is what is used to redirect audio, and the audio in the console WS goes to the speakers. 该Windows Station用来重定向音频,控制台WS中的音频传递给扬声器。 All other audio either is redirected to the network station they're using, or does nothing. 所有其他音频或者重定向到他们正在使用的网络站,或者什么都不做。

A more complex answer is that it might be possible, since the Windows Audio service is itself another service, and you might be able to interact with it directly, but this would be very low level and something you are probably not skilled enough to do. 一个更复杂的答案是可能的,因为Windows音频服务本身就是另一项服务,您也许可以直接与之交互,但这可能是一个很低的水平,并且您可能不够熟练。

Finally, it's possible to make services interact with the desktop. 最后,可以使服务与桌面进行交互。 However, this is considered a deprecated function and is not always easy to use. 但是,此功能被认为已弃用,并不总是易于使用。 It's also a huge security vulnerability, and makes your service susceptible to being used by malware to compromise a machine. 这也是一个巨大的安全漏洞,使您的服务易于被恶意软件破坏计算机。

I've been searching all over the internet whole the last night. 昨晚我一直在整个互联网上搜寻。 This question has been answered so many times but a simple answer is never given. 这个问题已经回答了很多次,但从未给出简单的答案。 If you have the same question there is a very simple but a tricky way to do something when the service asks for it. 如果您有相同的问题,则在服务要求时,有一种非常简单但棘手的方法来做某事。

Let's say you want to play a song when service starts. 假设您要在服务启动时播放歌曲。

first of all create an EventLog class: 首先创建一个EventLog类:

public class EventLogEngine
{
    private string _sourceName, _logName;
    public EventLogEngine(string sourceName, string logName)
    {
        if (!EventLog.SourceExists(sourceName))
            EventLog.CreateEventSource(sourceName, logName);
        _sourceName = sourceName; _logName = logName;
    }
    public void WriteLog(string message, EventLogEntryType eventType, int Id)
    {
        EventLog.WriteEntry(_sourceName, message, eventType, Id);
    }
}

protected override void OnStart(string[] args)
{
 EventLogEngine eventWriter = new EventLogEngine("mySource","myLog");
eventWriter.WriteLog("sourceName","Service started",EventLogEntryType.Information,"anyId");
}

There is nothig about playing a sound till here and there is nothing complicated yet. 直到这里都没有播放声音的痕迹,而且还没有什么复杂的。 But how to play a sound or do something else? 但是如何播放声音或做其他事情呢? Here is the answer :) 这是答案:)

1-Go to control panel and open Event Viewer 1-转到控制面板并打开事件查看器

2-Find your event log and click on it 2-找到您的事件日志,然后单击它

在此处输入图片说明

3-On the right panel you will see your entries which you have write through your code. 3-在右侧面板上,您将看到通过代码编写的条目。

4-Right click on the entry and select Attach Task To This Event! 4-右键单击条目,然后选择“将任务附加到此事件”!

在此处输入图片说明

So far you should have understood what I am going to do. 到目前为止,您应该已经了解我将要做什么。 right? 对?

5-Select that option and declare what do you want to do when this entry is set. 5-选择该选项,并声明设置此条目后要执行的操作。 You can simply attach as many as tasks you wish. 您可以简单地附加任意数量的任务。

在此处输入图片说明

Now write a program that plays a sound (Ex:in vb6) and tell Event Viewer to carry out this program each time this entry gets written(each time your service starts) 现在,编写一个播放声音的程序(例如,在vb6中),并在每次写入该条目时(每次启动服务时)告诉Event Viewer执行该程序。

It is possible to play sounds from a windows service. 可以从一个窗口服务播放声音。

Play wave file from a Windows Service (C#) 从Windows服务(C#)播放wave文件

Playing a sound from a service doesn't violate the rules of interactivity because it's not an interactive function: it's a notification. 从服务播放声音不会违反交互规则,因为它不是交互功能:它是通知。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM