一个exe中的多个Windows服务

时间:2009-05-03 05:55:55

标签: c# windows windows-services

我正在尝试构建多个Windows服务来执行不同的操作。例如,我需要Windows服务:

  1. 通过电子邮件发送每日报告
  2. 每30分钟定期清理一些存档信息
  3. 我需要Windows服务执行的任务是不同的,所以我不喜欢将它们全部集中在一个服务中的想法。

    到目前为止我所拥有的是Visual Studio 2008中的一个项目。我已经创建了一个Windows服务,我在OnStart事件上设置了一个计时器(它只是每5秒写一个文本文件进行测试目的)。然后我在项目中添加了一个安装程序,当我运行InstallUtil.exe时,一切正常。

    当我向同一个项目添加第二个Windows服务时出现问题。我再次设置OnStart代码,使用相同的日志信息(略有不同,以便我可以判断哪个服务正在写入日志)。使用第二个Windows服务,我在Program.cs中更改了Main事件:

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

    到:

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

    此时,没有编译时错误,但Service2服务从不执行任何操作......日志记录任务永远不会触发。

    我将其缩小到第二个服务没有与之关联的“安装程序”这一事实。然后,我尝试按照第一项服务的方式添加安装程序(即,右键单击服务设计器,然后单击“添加安装程序”)。现在,当我转到ProjectInstaller.cs文件时,那里有另一个serviceInstaller(serviceInstaller2)。

    现在当我构建项目并尝试安装服务时,我转到“服务”控制面板窗口,我尝试启动Service1,收到以下错误消息:

      

    Windows无法在本地计算机上启动Service1服务。

         

    错误1083:此服务配置为运行的可执行程序未实现该服务。

    如果我尝试启动Service2,也会收到相同的错误消息(当然,错误消息标识Service2除外)。

    为了从一个exe运行两个服务,我是否缺少一些东西?

7 个答案:

答案 0 :(得分:15)

我已经弄清楚如何拥有一个可执行文件但有两个服务。每个服务都以自己的名称和启动/停止的能力安装到服务管理器。我想这就是你想要的,对吗?这是我做的:

  1. 创建了一个服务项目。
  2. 为同一项目添加了第二项服务(具有唯一的服务名称)。
  3. 为两个服务(ServiceA和ServiceB)添加了安装程序。
  4. 在ProjectInstaller.Designer.vb文件中,我更改了Me.Installers.AddRange行以显示两个服务安装程序。 (Me.ServiceInstaller1,Me.ServiceInstaller2)
  5. 在主服务的主入口点(在我的情况下为ServiceA),我将ServicesToRun变量设置为ServiceBase数组,其中包含我希望它运行的所有服务(ServiceA和ServiceB)。这是一个重要的步骤,因为服务管理器根据此处的参数数量设置属性 - 要么允许同一个exe的多个实例,要么只允许单个实例。
  6. 添加安装程序项目并使用服务输出。
  7. 使用“服务”的输出添加自定义操作。
  8. 您可以在此处找到演示代码:
    http://code.google.com/p/multi-service-install/

    享受!

答案 1 :(得分:5)

我想你们已经解决了这个问题,但是如果其他人需要它,我会发布这个问题的答案,这个问题今天花了我几个小时。 解决方案不是添加另一个项目安装程序,而是添加服务安装程序,它是项目安装程序的一个组件。新添加的服务安装程序必须配置第二个服务名称。

答案 2 :(得分:2)

我今天遇到了类似的问题,并设法解决了这个问题。

首先,我确保每个服务都有一个有意义且唯一的ServiceName属性。该生成器为这两个服务提供了相同的名称,这些服务没有帮助。

然后我删除并重新生成了ProjectInstaller类,并为每个类添加了安装程序。我确保它们都是在静态Main方法中实例化的。

我现在可以使用一个dll安装这两个服务,但不幸的是,当我启动其中一个服务时,它似乎执行了自身和其他服务的功能。也就是说,两个服务都在运行(即使计算机管理器中只有一个服务显示为“已启动”)。我还在努力想出那个......

答案 3 :(得分:1)

我实际上正在构建一些与你想到的非常相似的东西。我决定做的(到目前为止)是我的所有'服务'(虽然它们不是服务,'控制器')实现特定的接口(使用init()和execute()操作)作为频率枚举)。

控制器是Windows服务,它在运行时从xml设置文件读取程序/ dll列表,并将它们加载到List中,并在它们定义的任何频率上调用它们的execute()方法(如果适用)。 / p>

在我的例子中,每个程序还包含一个usercontrol,它被加载到控制器的标签页中,允许用户控制/修改它。如果你有兴趣,我会发布代码。

不确定是否清楚。我实际上是从另一个SO用户那里得到了这个想法,他实现了类似的东西但我现在找不到那个帖子。

答案 4 :(得分:1)

我使用sc.exe轻松完成此任务。 http://support.microsoft.com/kb/251192

例如:sc create "My Display Service Name" binpath= "c:\app\mysvc.exe --service"

注意:每个相等的值应该在其值之前有 space ,正如您可以看到'binpath'

答案 5 :(得分:0)

我今天遇到了同样的问题,并设法解决了这个问题。 在我的情况下,我只需要打开我的服务的* .designer.cs文件,并确保正确设置服务名称。更重要的是,* Installer.Designer.cs中应该使用相同的名称,如果你有* Installer.cs中的代码。

我认为只会因名称不匹配而发生此错误。

希望这有帮助

答案 6 :(得分:0)

在一个可执行文件中安装2个不同且不相关的服务对我来说很有趣。虽然它可以让它发挥作用,但它并没有使它正确。

从听起来,你需要以不同的间隔执行一些不同的任务,你的任务可能相关也可能不相关。你看过Quartz.NET了吗?这听起来非常适合您的需求。

http://quartznet.sourceforge.net/features.html