什么是Windows服务失败的正确方法? [英] What is the proper way for a Windows service to fail?

查看:128
本文介绍了什么是Windows服务失败的正确方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我继承了C#编写的Windows服务。在罕见的情况下它失败得很惨。然而,这并不是在所有清楚如何失败良好。罗斯本内特优雅指出问题在字节.COM 。为简单起见,我将只是引述他在这里的缘故。




伙计们!



我一直在到处找这个,
,但我似乎无法撼动任何
文档了MSDN,或者从
谷歌。我已经审查了关于在MSDN,我所在开发Windows服务
每.NET
文章。



我正在开发一个Windows服务
应用。该服务从那里被另一个经理申请存入
系统
注册表(HKLM)读取它的
配置数据。没有
的问题在那里。



该服务使用一个工作线程做
工作。线程在
的OnStart()创建的,并暗示在调用OnStop /加盟/处置
()。再一次,没有任何问题。



一切精美的作品时:




  1. 系统管理员先后成立了一切正确的,而

  2. 国外网络资源都可达。



不过,当然,我们作为开发人员只需
不能依赖:




  1. 已经建立的一切系统管理员正确,或

  2. 国外网络资源可到达。



真的,我们需要的是为
服务应用程序有死在了自己的一些方法
。如果网络
的资源出现故障,我们需要
服务停止。但更多的
点,我们需要SCM知道它有
自行停止协议。 SCM需要
要知道,服务有
失败......并没有刚刚被关闭
跌的人。



呼唤回归或抛出
异常的OnStart()方法
不是,服务业也会有帮助的还是
在启动过程。该SCM去
欢快上和过程保持
运行在任务管理器 - 虽然
它实际上没有这样做,因为$ b $什么b中的辅助线程永远不会创建
,并开始

使用ServiceController的实例,
没有做到这一点,无论是。这似乎
单片机作为一个正常关机 - 不是
服务失败。所以没有
恢复操作或重新启动的发生。
(此外,还有MSDNful文档$ B约
ServiceBase后裔使用
ServiceController的把事情
与自身发生的危险$ B警告。)



我读过的文章这里的人们
摆弄PInvoking调用
本机代码只是设置
停止状态标志单片机。但是,
不关闭
服务中运行的进程。



我真的很想知道预期的$ B $乙方式:




  1. 从该服务,其中

  2. 中关闭一个服务
  3. 的SCM是appropriatedly通知服务已停止,和

  4. 的过程中从任务管理器中消失。



涉及ServiceControllers
解似乎并不合适,如果只有
,因为2是不满意。 (那
Framework文档专门
contraindicates做承载重量的
好对付,顺便说一句。)



我会很感激任何建议,
指向文档,甚至
理由充分的猜想。 :-)哦!和
我完全高兴招待了
我已经错过了这一点。



最亲切,



罗斯·贝内特



解决方案

在本机代码的最佳做法是调用 SetServiceStatus 具有非零退出代码来表示1) 。它停了下来,2)出事了。



在托管代码中,你可以实现通过获取单片机通过的的ServiceBase.ServiceHandle物业和p / Invoke的-ING在Win32 API。



我不明白为什么会SCM对待这有任何不同设置 ServiceBase.ExitCode 属性非零,然后调用 ServiceBase.Stop ,其实。的P / Invoke是多一点或者直接,如果服务处于恐慌状态。


I have inherited a Windows service written in C#. Under rare conditions it fails badly. However, it isn't at all clear how to fail well. Ross Bennett states the problem elegantly at bytes.com. For the sake of simplicity I will just quote him here.

Ahoy, Folks!

I've been looking all over for this, but I just can't seem to shake any documentation out of the MSDN or from Google. I've reviewed every .NET article on developing Windows Services in the MSDN I've located.

I'm developing a Windows Service application. This service reads its configuration data from the system registry (HKLM) where it was deposited by another "manager" application. No problems there.

The service uses a worker thread to do its work. The thread is created in the OnStart() and signaled/joined/disposed in the OnStop(). Again, no problems.

Everything works beautifully when:

  1. The system administrator has set up everything properly, and
  2. the foreign network resources are all reachable.

But of course, we as developers simply can't rely on:

  1. The system administrator having set up everything properly, or
  2. the foreign network resources being reachable.

Really, what we need is for the service application to have some way of dying on its own. If a network resource goes down, we need the service to stop. But more to the point, we need the SCM to know it has stopped on its own accord. SCM needs to know that the service has "failed"...and hasn't just been shut down by someone.

Calling "return" or throwing an exception in the "OnStart()" method isn't even helpful for services still in the start-up process.. The SCM goes merrily on and the process keeps running in the Task Manager--though it's not actually doing anything since the worker thread was never created and started.

Using a ServiceController instance doesn't do it, either. That appears to the SCM as a normal shutdown--not a service failure. So none of the recovery actions or restarts happen. (Also, there is MSDNful documentation warning about the perils of a ServiceBase descendant using a ServiceController to make things happen with itself.)

I've read articles where people were messing about with PInvoking calls to the native code just to set the "Stopped" status flag in the SCM. But that doesn't shut down the process the service is running within.

I'd really like to know the Intended Way of:

  1. Shutting down a service from within the service, where
  2. The SCM is appropriatedly notified that the service has "Stopped", and
  3. The process disappears from the Task Manager.

Solutions involving ServiceControllers don't seem to be appropriate, if only because 2 is not satisfied. (That the Framework documentation specifically contraindicates doing that carries a good deal of weight, incidentally.)

I'd appreciate any recommendations, pointers to documentation, or even well-reasoned conjecture. :-) Oh! And I'm perfectly happy to entertain that I've missed the point.

Most cordially,

Ross Bennett

解决方案

Best practice in native code is to call SetServiceStatus with a non-zero exit code to indicate 1) it's stopped and 2) something went wrong.

In managed code, you could achieve the same effect by obtaining the SCM handle through the ServiceBase.ServiceHandle Property and P/Invoke-ing the Win32 API.

I don't see why the SCM would treat this any differently than setting the ServiceBase.ExitCode property non-zero and then calling ServiceBase.Stop, actually. P/Invoke is a bit more direct perhaps, if the service is in panic mode.

这篇关于什么是Windows服务失败的正确方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆