简体   繁体   English

在 onStart() 方法中停止 windows 服务

[英]stop windows service in onStart() method

I want to stop windows service in onStart() method when customer doesn't have a license.当客户没有许可证时,我想在onStart()方法中停止 windows 服务。 I use service.Stop() , but it does not work.我使用service.Stop() ,但它不起作用。

protected override void OnStart(string[] args)
{
    try
    {
        _bridgeServiceEventLog.WriteEntry("new OnStart");
        if (LicenseValidetor.ValidCountAndTypeDevices())
        {
            WsInitializeBridge();
        }
        else
        {
            service = new ServiceController("BridgeService");
            service.Stop();
            _bridgeServiceEventLog.WriteEntry("LicenseValidetor Error");
        }
        _bridgeServiceEventLog.WriteEntry("end Start");
    }
    catch (Exception e)
    {
        _bridgeServiceEventLog.WriteEntry("error In onstart method ");
    }

}

You cannot stop a service from within the OnStart method of that same service.您不能从同一服务的OnStart方法中停止服务。

The ServiceController.Stop method internally calls ControlService (or it's Ex counterpart). ServiceController.Stop方法在内部调用ControlService (或者它的Ex对应物)。 Notice that one of the reasons that this function can fail is:请注意,此功能可能失败的原因之一是:

ERROR_SERVICE_CANNOT_ACCEPT_CTRL The requested control code cannot be sent to the service because the state of the service is SERVICE_STOPPED , SERVICE_START_PENDING , or SERVICE_STOP_PENDING . ERROR_SERVICE_CANNOT_ACCEPT_CTRL请求的控制代码无法发送到服务,因为服务的状态是SERVICE_STOPPEDSERVICE_START_PENDINGSERVICE_STOP_PENDING

Well, guess what - when you're inside your OnStart method, the state of your service is SERVICE_START_PENDING .好吧,你猜怎么着 - 当你在你的OnStart方法中时,你的服务状态是SERVICE_START_PENDING


The correct way to cope with this situation is to signal any other threads that you may have started to have them exit, and then to exit your OnStart method.处理这种情况的正确方法是通知任何其他线程您可能已经开始让它们退出,然后退出您的OnStart方法。 The service control manager will notice that the process has exited and revert your service status to SERVICE_STOPPED .服务控制管理器会注意到该进程已退出并将您的服务状态恢复为SERVICE_STOPPED It may also notify an interactive user that "The service started and then stopped" or words to that effect.它还可以通知交互式用户“服务启动然后停止”或具有该效果的文字。

I have noticed that your not waiting to ensure that the Service has actually stopped or if it is even running in the first instance.我注意到您没有等待确保服务实际上已经停止,或者它是否在第一个实例中运行。

Do this :-做这个 :-

protected override void OnStart(string[] args)
{
    try
    {
        _bridgeServiceEventLog.WriteEntry("new OnStart");
        if (LicenseValidetor.ValidCountAndTypeDevices())
        {
            WsInitializeBridge();
        }
        else
        {
            int time = 10000;

            TimeSpan timeout = TimeSpan.FromMilliseconds(time);

            service.Stop();
            service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);

            _bridgeServiceEventLog.WriteEntry("LicenseValidetor Error");
        }
        _bridgeServiceEventLog.WriteEntry("end Start");
    }
    catch (Exception e)
    {
        _bridgeServiceEventLog.WriteEntry("error In onstart method ");
    }
}

I want to add that "simply not starting any workers" may not work (or perhaps I am being just plain stupid ;) ).我想补充一点,“简单地不启动任何工人”可能不起作用(或者我可能只是愚蠢;))。

I built a service, with a try/catch(all) around my OnStart code.我构建了一个服务,在我的 OnStart 代码周围有一个 try/catch(all)。 Because of a missing line in my .config file it crashed with an IOException, before it started any worker thread.由于我的 .config 文件中缺少一行,它在启动任何工作线程之前因 IOException 崩溃。 The exception skipped over my thread starters.异常跳过了我的线程启动器。 No thread was started by my code.我的代码没有启动线程。 Honestly.诚实地。

But the service DID NOT STOP.但服务并没有停止。 I don't know why.我不知道为什么。 As a desperate measure, I rethrew the exception, that helped.作为一种绝望的措施,我重新提出了例外,这有帮助。

I am still wondering if the file system watcher threads in Enterprise Library configuration were the problem.我仍然想知道企业库配置中的文件系统观察程序线程是否是问题所在。 EntLib is woven to deeply into my code to remove it as an experiment, so I did not investigate further. EntLib 深入到我的代码中,作为实验将其删除,所以我没有进一步调查。

The accepted answer explains why what you are doing doesn't work but doesn't offer a good solution.接受的答案解释了为什么您正在做的事情不起作用但没有提供好的解决方案。

There are a couple of things your code isn't doing that it should.您的代码有几件事没有做它应该做的。

  1. Set the .ExitCode to indicate that your service is in an error state.设置.ExitCode以指示您的服务处于错误 state。
  2. Throw an exception.抛出异常。 Not having a license is exceptional.没有执照是例外。 Throw it.丢它。

EXAMPLE:例子:

protected override void OnStart(string[] args)
{
    _bridgeServiceEventLog.WriteEntry("new OnStart");
    try
    {        
        if (LicenseValidetor.ValidCountAndTypeDevices())
        {
            WsInitializeBridge();
        }
        else
        {
            throw new ApplicationException("LicenseValidetor Error");
        }
    }
    catch (Exception e)
    {
        this.ExitCode = e.HResult
        _bridgeServiceEventLog.WriteEntry($"error In onstart method: {e.Message}");
        throw
    }

    _bridgeServiceEventLog.WriteEntry("end Start");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM