C# 以编程方式授予/拒绝windows服务的桌面功能

C# 以编程方式授予/拒绝windows服务的桌面功能,c#,windows-services,C#,Windows Services,我知道我可以通过在服务属性中将CanStop选项设置为false来拒绝onStopfeauture。这不是我想要的,因为这将永久拒绝onStop功能 我想要的是以编程方式授予/拒绝停止功能。我的服务生命周期非常简单: starts => { run some action => sleeps for 2 minutes } x nTimes => stop 我要做的是在服务运行时拒绝停止功能,并在服务空闲时授予该功能(即,如果用户试图在不允许的情况下停止它,则不会发生任何事情

我知道我可以通过在服务属性中将
CanStop
选项设置为
false
来拒绝
onStop
feauture。这不是我想要的,因为这将永久拒绝
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");
        }
    }

不要这样做。当要求停止时,服务必须立即停止(5秒或更短)。若您延迟或拒绝来自SCM的停止请求,当用户重新启动计算机时,您肯定会惹恼他们。您可以动态地更改服务配置,但这可能不是一个好主意,因为频繁更改服务配置听起来并不正确

service STOP命令的语义就是这样——服务必须在最早的安全位置停止。你的行动与那不同。我建议实现一个能够准确表示语义的自定义机制(即,不要重用STOP命令)。有两种方法可以做到这一点:

  • 任何一种IPC机制。命名事件可能是最容易实现的。服务将创建一个命名事件,并在一个后台线程中等待它。设置事件时(由用户模式应用程序设置),它将执行必要的检查,并有条件地调用
    ServiceBase.Stop

  • 发明一个自定义服务控制命令。这很容易做到,只需覆盖
    ServiceBase.OnCustomCommand
    ,组成一个128到255之间的整数,代表您的命令,并实现OnCustomCommand来调用
    ServiceBase.Stop
    。要向服务发送自定义命令,您可以使用API或
    sc-control
    命令。假设您在新命令中使用234:


  • sc-control-MyService 234

    服务运行时间长吗?如果不是,为什么不处理一个停止来正常结束所有线程(例如,等待线程完成,然后停止)?最好的方法可能是尽快停止服务,并在开始时验证损坏的操作并恢复它。