我知道我可以通过在服务的属性中将onStop
选项设置为CanStop
来拒绝false
。这不是我想要的,因为这将永久地否定onStop
能力。
我想要的是以编程方式授予/拒绝停止功能。我的服务生命周期非常简单:
starts => { run some action => sleeps for 2 minutes } x nTimes => stop
当服务处于运行状态时,我会拒绝停止功能,并在服务空闲时授予该功能(例如,如果用户试图在不允许的情况下停止发生任何事情,那么服务确实会自行停止)。
这就是我的服务编写方式,我有各种方法可以了解是否空闲。
partial class Service : ServiceBase
{
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private DateTime _lastRun = DateTime.Now;
private System.Timers.Timer _timer = new System.Timers.Timer(Convert.ToInt32(ConfigurationManager.AppSettings["pollingInterval"]) * 60 * 1000);
public Service()
{
InitializeComponent();
}
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
_timer.Enabled = false;
DateTime now = DateTime.Now;
if (now.Minute > _lastRun.Minute)
{
ClientVS cvs = new ClientVS();
cvs.run();
}
_lastRun = now;
_timer.Enabled = true;
}
protected override void OnStart(string[] args)
{
log.Info("Started");
_timer.Elapsed += timer_Elapsed;
_timer.Start();
}
protected override void OnStop()
{
log.Info("Stopped");
}
}
答案 0 :(得分:0)
不要这样做。请求停止时,服务必须立即停止(5秒或更短)。如果您延迟或拒绝来自SCM的停止请求,您可以保证在重新启动计算机时骚扰您的用户。您可以动态地更改服务配置,但这可能是个坏主意,因为经常更改serice配置听起来不对。
服务STOP命令的语义就是这样 - 服务必须在最早的安全位置停止。你的行动与此不同。我建议的是实现一个完全代表你的语义的自定义机制(也就是说,不要重用STOP命令)。有几种方法可以做到这一点:
任何类型的IPC机制。命名事件可能最容易实现。服务将创建一个命名事件,并在其中一个后台线程中等待它。设置事件时(通过您的用户模式应用程序),它将进行必要的检查并有条件地调用ServiceBase.Stop
。
创建自定义服务控制命令。这很容易做到,只需覆盖ServiceBase.OnCustomCommand
,组成一个128到255之间的整数,代表你的命令,并实现OnCustomCommand以有条件地调用ServiceBase.Stop
。要将自定义命令发送到服务,您可以使用API或sc control
命令。假设你作为新命令编造234:
sc control MyService 234