如何从.NET代码向.NET Windows服务发送自定义命令?

Ham*_*jan 35 c# windows-services restart .net-4.0

如下面的链接,可以使用C#代码停止,启动和"停止,然后启动"服务.

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

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

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

此功能很重要,但很危险.我想让它相当隐蔽,有点安全,同时保持简单,并确保在执行常规杂务而不重启时,这对我的Windows服务的性能影响可以忽略不计.

如果我必须轮询某个文件或打开一个端口并花费太多的CPU来做这件事,那将不是一个好的解决方案.我也想保持这个简单易用(抱歉重复).

dtb*_*dtb 58

您可以使用ServiceController.ExecuteCommand将"命令"发送到服务:

const int SmartRestart = 222;

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

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

该服务可以通过重写ServiceBase.OnCustomCommand来响应该命令:

protected override void OnCustomCommand(int command)
{
    if (command == SmartRestart)
    {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 一些额外的信息:DOS SC.exe命令也可以发送这些命令,安全权限允许...例如'SC CONTROL YOURSERVICENAME 200' (17认同)
  • 起初这对我不起作用。然后我发现命令整数必须介于128和255之间...(如MSDN页面上所述)。避免头痛,并牢记这一点。 (3认同)

Ali*_*tad 14

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

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

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

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

  • 如果您计划发送参数,这个答案是优越的(并且是必需的). (3认同)