C# 一个 exe 中的多个 Windows 服务
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/816437/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Multiple Windows Services in One exe
提问by dp.
I am trying to build several Windows services to do different things. For instance, I need Windows services that will:
我正在尝试构建几个 Windows 服务来做不同的事情。例如,我需要 Windows 服务:
- Send a daily report via email
- Periodically cleanup some archived info every 30 minutes
- etc.
- 通过电子邮件发送每日报告
- 每 30 分钟定期清理一些存档信息
- 等等。
The tasks I need the windows services to do are distinct so I don't really like the idea of having them all in one service.
我需要 Windows 服务完成的任务是不同的,所以我真的不喜欢将它们全部放在一个服务中的想法。
What I've got so far is a project in Visual Studio 2008. I've created a windows service, I've set up a timer on the OnStart event (it just writes to a text file every 5 seconds for testing purposes). I then added an Installer to the project and when I run InstallUtil.exe, everything works fine.
到目前为止,我拥有的是 Visual Studio 2008 中的一个项目。我创建了一个 Windows 服务,我在 OnStart 事件上设置了一个计时器(它只是每 5 秒写入一个文本文件以进行测试)。然后我向项目添加了一个安装程序,当我运行 InstallUtil.exe 时,一切正常。
The problem comes in when I add a second windows service to the same project. I set up the OnStart code again, with the same logging info (slightly different so I can tell which service is writing to the log). With the second windows service, I changed the Main event in Program.cs from:
当我向同一个项目添加第二个 Windows 服务时,问题就出现了。我再次设置了 OnStart 代码,使用相同的日志信息(略有不同,因此我可以判断哪个服务正在写入日志)。使用第二个 Windows 服务,我将 Program.cs 中的 Main 事件从:
static void Main(string[] args)
{
ServiceBase[] ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
}
to:
到:
static void Main(string[] args)
{
ServiceBase[] ServicesToRun = new ServiceBase[]
{
new Service1(),
new Service2()
};
ServiceBase.Run(ServicesToRun);
}
At this point, there are no compile time errors, but the Service2 service never does anything...the logging task never fires.
此时,没有编译时错误,但 Service2 服务从不做任何事情……日志任务从不触发。
I narrowed it down to the fact that the second service has no "Installer" associated with it. I then tried to add an Installer the way I did with the first service (i.e., right click on the service designer, and click "Add Installer"). Now, when I go to the ProjectInstaller.cs file, there is another serviceInstaller there (serviceInstaller2).
我将范围缩小到第二个服务没有与之关联的“安装程序”这一事实。然后我尝试按照我对第一个服务所做的方式添加安装程序(即,右键单击服务设计器,然后单击“添加安装程序”)。现在,当我转到 ProjectInstaller.cs 文件时,那里有另一个 serviceInstaller (serviceInstaller2)。
Now when I build the project and try to install the services, and I go to the "Services" control panel window, and I try to start Service1, I get the following error message:
现在,当我构建项目并尝试安装服务时,我转到“服务”控制面板窗口,并尝试启动 Service1,我收到以下错误消息:
Windows could not start the Service1 service on the Local Computer.
Error 1083: The executable program that this service is configured to run in does not implement the service.
Windows 无法在本地计算机上启动 Service1 服务。
错误 1083:配置此服务运行的可执行程序未实现该服务。
I get the same error message if I try to start Service2 as well (with the exception that the error message identifies Service2, of course).
如果我也尝试启动 Service2,我也会收到相同的错误消息(当然,错误消息标识了 Service2)。
Is there something I am missing in order to get two services running from one exe?
为了从一个 exe 运行两个服务,我缺少什么吗?
回答by Steven Evers
I'm actually building something very similar to what you're thinking of. What I've decided to do (thus far) is have all of my 'services' (though they aren't services, the one 'controller' is) implement a particular interface (with init() and execute() operations as well as a FREQUENCY enumeration).
我实际上正在构建与您所想的非常相似的东西。我决定做的(到目前为止)是让我所有的“服务”(虽然它们不是服务,但一个“控制器”是)实现一个特定的接口(还有 init() 和 execute() 操作)作为频率枚举)。
The controller is the windows service and it reads the list of programs/dlls from an xml settings file at runtime and loads them into a List and calls their execute() method (if applicable) on whatever frequency they have defined.
控制器是 Windows 服务,它在运行时从 xml 设置文件读取程序/dll 列表,并将它们加载到列表中,并以它们定义的任何频率调用它们的 execute() 方法(如果适用)。
In my case, each program also contains a usercontrol that is loaded into a tab page of the controller that allows the user to control/modify it. I'll post code if you're interested.
在我的例子中,每个程序还包含一个用户控件,它被加载到控制器的标签页中,允许用户控制/修改它。如果你有兴趣,我会发布代码。
Not sure if that was clear. I actually got the idea from another SO user who implemented something similar but I can't find that post now.
不知道这是否清楚。我实际上是从另一个 SO 用户那里得到了这个想法,他实现了类似的东西,但我现在找不到那个帖子。
回答by Steven Evers
I had a similar problem today, and managed to resolve it.
我今天遇到了类似的问题,并设法解决了它。
Firstly, I made sure that each of the services had a meaningful and unique ServiceName property. The generator gave both of the services the same name which would not have helped.
首先,我确保每个服务都有一个有意义且唯一的 ServiceName 属性。生成器为这两个服务提供了相同的名称,这无济于事。
I then removed and regenerated the ProjectInstaller class, and added installers for each of the classes. I made sure they were both instantiated in the static Main method.
然后我删除并重新生成了 ProjectInstaller 类,并为每个类添加了安装程序。我确保它们都在静态 Main 方法中实例化。
I can now install the two services with the one dll, but unfortunately when I start one of the services it seems to perform the functions of both itself and the other service. That is, both of the services are running (even though only one of the services appears as 'Started' in Computer Manager). I'm still trying to figure that one out...
我现在可以用一个 dll 安装这两个服务,但不幸的是,当我启动其中一个服务时,它似乎执行了它本身和另一个服务的功能。也就是说,这两个服务都在运行(即使只有一个服务在计算机管理器中显示为“已启动”)。我还在想办法解决这个问题...
回答by Usman Akram
I had the same problem today and managed to fix it. In my case I just had to open the *.designer.cs files of my services and make sure that the service name is set correctly. More importantly the same name should be used in the *Installer.Designer.cs and if you have code in *Installer.cs.
我今天遇到了同样的问题并设法解决了它。就我而言,我只需要打开我的服务的 *.designer.cs 文件并确保服务名称设置正确。更重要的是,*Installer.Designer.cs 中应该使用相同的名称,如果您在 *Installer.cs 中有代码。
I think this error occurs only because of name mismatch.
我认为这个错误只是因为名称不匹配。
Hope this helpds
希望这有帮助
回答by Ogren
I guess that you guys have already solved this, but in case that some else needs it, I'll post an answer to this issue which took me several hours today. The solutions is not to add another project installer, but a service installer, which is a component on the project installer. That newly added service installer has to have second service name configured.
我想你们已经解决了这个问题,但是如果其他人需要它,我会发布这个问题的答案,这个问题今天花了我几个小时。解决方案不是添加另一个项目安装程序,而是添加一个服务安装程序,它是项目安装程序上的一个组件。新添加的服务安装程序必须配置第二个服务名称。
回答by Scott
I have figured out how to have one executable but two services. Each service installs to the service manager with its own name and ability to start/stop. I think this is what you're wanting, correct? Here is what I did:
我已经想出了如何拥有一个可执行文件但有两个服务。每个服务都以自己的名称和启动/停止能力安装到服务管理器。我想这就是你想要的,对吗?这是我所做的:
- Created a service project.
- Added a second service to the same project (with a unique service name).
- Added an installer to both services (ServiceA and ServiceB).
- In the ProjectInstaller.Designer.vb file I changed the Me.Installers.AddRange line to show both of the service installers. (Me.ServiceInstaller1, Me.ServiceInstaller2)
- In the Main entry point of the main service (ServiceA in my case), I set the ServicesToRun variable to an array of ServiceBase containing all the services that I want it to run (ServiceA and ServiceB). This is an important step as the service manager sets a property based on the number of arguments here - either to allow multiple instances of the same exe or only a single instance.
- Add an installer project and use the output of Services.
- Add a custom action using the output from Services.
- 创建了一个服务项目。
- 向同一个项目添加了第二个服务(具有唯一的服务名称)。
- 向两个服务(ServiceA 和 ServiceB)添加了一个安装程序。
- 在 ProjectInstaller.Designer.vb 文件中,我更改了 Me.Installers.AddRange 行以显示两个服务安装程序。(Me.ServiceInstaller1, Me.ServiceInstaller2)
- 在主服务(在我的例子中为 ServiceA)的 Main 入口点中,我将 ServicesToRun 变量设置为包含我希望它运行的所有服务(ServiceA 和 ServiceB)的 ServiceBase 数组。这是重要的一步,因为服务管理器根据此处的参数数量设置属性 - 允许同一 exe 的多个实例或仅允许单个实例。
- 添加安装程序项目并使用服务的输出。
- 使用服务的输出添加自定义操作。
You can find the demo code here:
http://code.google.com/p/multi-service-install/
您可以在此处找到演示代码:http:
//code.google.com/p/multi-service-install/
Enjoy!
享受!
回答by Walter
Installing 2 distinct and unrelated services in one executable has a funny smell to me. While it's possible to get it to work, it doesn't make it right.
在一个可执行文件中安装 2 个不同且不相关的服务对我来说很有趣。虽然有可能让它工作,但它并不正确。
From what it sounds like, you need to perform some different tasks at various intervals and your tasks may or may not be related. Have you looked into Quartz.NET? It sounds like a good fit for your needs.
听起来,您需要以不同的时间间隔执行一些不同的任务,并且您的任务可能相关,也可能不相关。你看过 Quartz.NET 吗?这听起来很适合您的需求。
回答by Pavan G R
I used sc.exe to accomplish this easily. http://support.microsoft.com/kb/251192
我使用 sc.exe 轻松完成此操作。http://support.microsoft.com/kb/251192
For ex: sc create "My Display Service Name" binpath= "c:\app\mysvc.exe --service"
例如: sc create "My Display Service Name" binpath= "c:\app\mysvc.exe --service"
Note: every equal should have spacebefore its value as you can see for 'binpath'
注意:每个相等都应该在其值之前有空格,如您在“binpath”中看到的那样