在 Windows 服务启动之间创建依赖关系

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5159257/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 16:18:26  来源:igfitidea点击:

create dependency between windows services startup

c#windows.net-4.0windows-services

提问by stackoverflowuser

I have created a windows service which is set to start automatically. This service connects to the database service on startup. The issue is the database service seems to start after my service. Is there is a programmatic way to define this dependency so that my service starts after the database service has started.

我创建了一个设置为自动启动的 Windows 服务。此服务在启动时连接到数据库服务。问题是数据库服务似乎在我的服务之后启动。是否有一种编程方式来定义此依赖项,以便我的服务在数据库服务启动后启动。

I found this article http://www.boyce.us/windows/servertipcontent.asp?ID=7which talks about adding a registry entry to do that. I would like to know if there is a C# way to do this?

我发现这篇文章http://www.boyce.us/windows/servertipcontent.asp?ID=7谈到添加一个注册表项来做到这一点。我想知道是否有 C# 方法可以做到这一点?

Update:

更新:

Adding to the above question. Here is another scenario. The services are being installed using installshied which does not need a projectinsaller. It seems installshield looks for classes deriving from ServiceBase class and installs each service. How to add the dependency in such a scenario?

补充上面的问题。这是另一个场景。正在使用不需要 projectinsaller 的 installshied 安装服务。似乎 installshield 寻找派生自 ServiceBase 类的类并安装每个服务。在这种情况下如何添加依赖项?

回答by Jay Riggs

You're looking for the ServiceInstaller.ServicesDependedOn Propertyfor your project's ServiceInstaller component.

您正在为您的项目的 ServiceInstaller 组件寻找ServiceInstaller.ServicesDependedOn 属性

From the article's Remarks section (and I bolded the part you're interested in):

来自文章的备注部分(我将您感兴趣的部分加粗):

A service can require other services to be running before it can start. The information from this property is written to a key in the registry. When the user (or the system, in the case of automatic startup) tries to run the service, the Service Control Manager (SCM) verifies that each of the services in the array has already been started.

If any service in the array is not running then, the SCM tries to start them. This includes services with Manual StartType.

If any service upon which this service depends fails to start, this service will not start. An exception is not thrown if the system is not started because there is no exception handling at the system level to detect this. Decide how to handle service start failures and implement this in your code. Typically, a dialog appears to the user at startup if a service fails to start.

If the service does not start, an entry is written to the Application event log.

The services upon which this service depends do not need to be in the same executable.

一个服务可能需要其他服务运行才能启动。来自该属性的信息被写入注册表中的一个键。当用户(或系统,在自动启动的情况下)尝试运行服务时,服务控制管理器 (SCM) 会验证阵列中的每个服务是否已启动。

如果阵列中的任何服务没有运行,SCM 会尝试启动它们。这包括具有 Manual StartType 的服务

如果此服务所依赖的任何服务无法启动,则此服务将不会启动。如果系统未启动,则不会抛出异常,因为在系统级别没有异常处理来检测这种情况。决定如何处理服务启动失败并在您的代码中实现它。通常,如果服务无法启动,则在启动时会向用户显示一个对话框。

如果该服务未启动,则会在应用程序事件日志中写入一个条目。

此服务所依赖的服务不需要位于同一个可执行文件中。

回答by real_yggdrasil

In addition to Jay Riggs' answer, here's and example of what you should add to the serviceinstaller to make your service dependent on the eventlog

除了 Jay Riggs 的回答之外,这里还有您应该添加到 serviceinstaller 以使您的服务依赖于事件日志的示例

Me.ServiceInstaller1.ServiceName = "Service1";
Me.ServiceInstaller1.ServicesDependedOn = new string[] {"EventLog"};

Off course, if you have another service dependency, change the 'Eventlog' to something else..

当然,如果您有其他服务依赖项,请将“事件日志”更改为其他内容。

回答by Switch

I use the advapi32.dll as I have full control over the installation. My services register themselves, set descriptions (though I use sc.exe), set dependencies, set restart on failures (also using sc.exe) etc.

我使用 advapi32.dll,因为我可以完全控制安装。我的服务会自行注册、设置描述(尽管我使用 sc.exe)、设置依赖项、设置失败时重新启动(也使用 sc.exe)等。

ChangeServiceConfig2 API is supposed to set descriptions, but doesn't seem to work in .NET

ChangeServiceConfig2 API 应该设置描述,但在 .NET 中似乎不起作用

The dependency is set by the CreateService API..

依赖项由 CreateService API 设置。

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern UIntPtr CreateService(UIntPtr SC_HANDLE, string lpSvcName, string lpDisplayName,
        uint dwDesiredAccess, uint dwServiceType, uint dwStartType, uint dwErrorControl, string lpPathName,
        string lpLoadOrderGroup, string lpdwTagId, string lpDependencies, string lpServiceStartName, string lpPassword);