服务导致SCM错误“报告无效的当前状态0”

我写了一个servlets,它充当本地网络服务器。 为了编写服务,我在MSDN上学习了如何使用ServiceBase类编写服务。

但是当我注册并启动服务时,我收到错误消息,如下所示。 我在开始和服务停止时得到了其中两个错误消息。 (示例=服务名称)。

示例服务已报告无效的当前状态0。

这是我服务的最小样本,包含所有相关部分。 代码以MSDN教程中提供的枚举和结构定义开头:

 public enum ServiceState { SERVICE_STOPPED = 0x00000001, SERVICE_START_PENDING = 0x00000002, SERVICE_STOP_PENDING = 0x00000003, SERVICE_RUNNING = 0x00000004, SERVICE_CONTINUE_PENDING = 0x00000005, SERVICE_PAUSE_PENDING = 0x00000006, SERVICE_PAUSED = 0x00000007, } [StructLayout(LayoutKind.Sequential)] public struct ServiceStatus { public long dwServiceType; public ServiceState dwCurrentState; public long dwControlsAccepted; public long dwWin32ExitCode; public long dwServiceSpecificExitCode; public long dwCheckPoint; public long dwWaitHint; }; 

在此之后,我写的服务代码减少到相关部分:

 namespace example { public partial class Service : ServiceBase { public Service() : base() { this.ServiceName = "ExampleService"; this.AutoLog = false; this.CanStop = true; this.CanShutdown = false; this.CanPauseAndContinue = false; this.CanHandlePowerEvent = false; this.CanHandleSessionChangeEvent = false; } protected override void OnStart(string[] args) { try { SetServiceState(ServiceState.SERVICE_START_PENDING, 100000); // ... initialise and start... SetServiceState(ServiceState.SERVICE_RUNNING); } catch (System.Exception ex) { SetServiceState(ServiceState.SERVICE_STOPPED); } } protected override void OnStop() { SetServiceState(ServiceState.SERVICE_STOP_PENDING, 100000); // ... stop service ... SetServiceState(ServiceState.SERVICE_STOPPED); } private void SetServiceState(ServiceState state, int waitHint = 0) { ServiceStatus serviceStatus = new ServiceStatus(); serviceStatus.dwCurrentState = state; serviceStatus.dwWaitHint = waitHint; SetServiceStatus(this.ServiceHandle, ref serviceStatus); } [DllImport("advapi32.dll", SetLastError=true)] private static extern bool SetServiceStatus(IntPtr handle, ref ServiceStatus serviceStatus); } } 

主要切入点很简单,因为:

 static void Main(string[] args) { ServiceBase.Run(new Service()); } 

如您所见,错误消息的数量与SetServiceState调用的数量相匹配。 如果我添加其他此类调用,则错误消息的数量会相应增加。

所以我假设,整个问题都在我调用SetServiceStatus API的方式,但我目前看不到问题。

你能发现问题吗?

无论如何这是使用C#和.NET构建服务的正确方法吗?

第一:

通常不需要调用SetServiceState方法。 如果您的服务确实需要很长时间来初始化(可以通过SERVICE_START_PENDING告诉SCM您还活着并需要几秒钟),则可能需要它。 通常,您在OnStart启动一个线程并尽快返回。

我在过去的几年里用C#编写了很多服务,但从来没有这样做过。

但是 – 我在MSDN示例代码中发现了一个错误(我自己测试了您的代码)。

ServiceStatus使用int或(更好的单位)替换long。 如果使用uint,则还必须在SetServiceState方法中更改此设置。

另见DWORD映射到int还是uint? 。

如果您对如何在C#中使用其他设置启动Windows服务感兴趣,可以查看我的博客条目:

http://www.rsprog.de/samplewindowsservice/

[更新2018-01-20]

我创建了一篇关于它的新文章,该文章使用了自我安装方法,该方法具有优势(至少对我而言),它不需要Visual Studio的安装项目扩展

http://www.rsprog.de/windowsserviceselfinstall/