42

如以下链接所示,可以使用 C# 代码停止、启动和“停止,然后启动”服务。

http://www.csharp-examples.net/restart-windows-service/

我已经烘焙了一个 .NET 服务,它实现了OnStartOnStop. 但是,我需要实现一个“智能重启”功能,而不仅仅是停止然后启动。如果那样的话,我需要将停机时间保持在几秒钟内(但是在这种情况下,如果干净地完成,停止 + 启动可能需要几分钟,而且我必须干净地完成它),并且系统的某些部分可用,而其他部分正在重新启动/刷新.

长话短说——在我开始实现这个OnSmartRestart功能之前,我想确保有一种相当简单的方法可以从另一个 C# 应用程序调用这个调用。

此功能很重要,但也很危险。我想让它相当隐藏,有点安全,也保持简单,并确保这对我的 Windows 服务的性能影响可以忽略不计,而它正在执行它的日常琐事而不是重新启动。

如果我必须轮询某个文件或打开一个端口并为此花费过多的 CPU,那将不是一个好的解决方案。我也想尽可能简单(抱歉重复)。

4

2 回答 2

64

您可以使用ServiceController.ExecuteCommand向服务发送“命令” :

const int SmartRestart = 222;

var service = new System.ServiceProcess.ServiceController("MyService");
service.ExecuteCommand(SmartRestart);
service.WaitForStatus(ServiceControllerStatus.Running, timeout);

您需要添加对 System.ServiceProcess.dll 程序集的引用。

该服务可以通过覆盖ServiceBase.OnCustomCommand对命令做出反应:

protected override void OnCustomCommand(int command)
{
    if (command == SmartRestart)
    {
        // ...
    }
}
于 2010-09-12T14:56:46.800 回答
17

在 windows 中与外部进程通信的常用方法是:

  1. 命名管道
  2. 插座
  3. COM 的 GetObject 获取对对象的引用,然后通过公开的接口调用其方法。

前两个已公开为 WCF,所以这是要走的路。第三个似乎与您的情况无关,而且已经过时了。

如果你需要在同一台机器上运行你的命令,你可以使用命名管道,但是强化使得它变得非常困难和麻烦。否则使用 WCF 的 TCP 命名绑定。

于 2010-09-12T15:00:49.743 回答